Avatar ·

Как программно изменить текст UIButton в Swift? (iOS)

Всем привет! Я новичок в iOS-разработке на Swift и столкнулся с проблемой: не могу понять, как правильно изменить текст кнопки программно, после того как она уже создана в сториборде. У меня есть простая кнопка, подключенная через IBOutlet: ```swift @IBOutlet weak var myButton: UIButton! ``` Я хочу, чтобы при нажатии на эту кнопку её текст менялся с "Нажми меня" на "Нажато!". Я пробовал писать такой код в действии (IBAction): ```swift @IBAction func buttonTapped(_ sender: UIButton) { myButton.text = "Нажато!" } ``` Но Xcode выдаёт ошибку: "Value of type 'UIButton' has no member 'text'". Я также пробовал `myButton.title = "Нажато!"` — тоже не работает. Пожалуйста, объясните, как правильно изменить текст кнопки. Желательно с примерами для разных состояний кнопки (normal, highlighted, selected). И ещё: если я создаю кнопку не в сториборде, а программно — подход будет отличаться? Заранее спасибо за помощь! <<>>

Проблема: у UIButton нет свойства text

В Swift UIButton — это не UILabel. У кнопки нет прямого свойства .text. Вместо этого для управления текстом используется метод setTitle(_:for:), который позволяет задать заголовок для каждого состояния кнопки отдельно.

Правильное решение: setTitle(_:for:)

Используйте следующий синтаксис:

myButton.setTitle("Нажато!", for: .normal)
  • .normal — обычное состояние (по умолчанию)
  • .highlighted — когда палец нажал на кнопку
  • .selected — когда кнопка выбрана (например, toggle)
  • .disabled — когда кнопка неактивна

Полный пример для IBAction

@IBOutlet weak var myButton: UIButton!

@IBAction func buttonTapped(_ sender: UIButton) {
    // Меняем текст для обычного состояния
    myButton.setTitle("Нажато!", for: .normal)
    
    // Дополнительно: меняем текст для состояния highlighted
    myButton.setTitle("Отпусти!", for: .highlighted)
    
    // Если нужно вернуть исходный текст — просто вызовите снова
    // myButton.setTitle("Нажми меня", for: .normal)
}

Как получить текущий текст кнопки?

Для чтения используйте метод title(for:):

let currentTitle = myButton.title(for: .normal)
print("Текущий текст: \(currentTitle ?? "нет текста")")

Создание кнопки программно — тот же подход

Если вы создаёте кнопку без сториборда, принцип не меняется:

let programmaticButton = UIButton(type: .system)
programmaticButton.frame = CGRect(x: 100, y: 100, width: 200, height: 50)
programmaticButton.setTitle("Нажми меня", for: .normal)
programmaticButton.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
view.addSubview(programmaticButton)

Внутри buttonTapped вы точно так же вызываете setTitle.

Работа с атрибутированным текстом (стилизация)

Если нужно изменить не только текст, но и цвет/шрифт — используйте setAttributedTitle(_:for:):

let attributes: [NSAttributedString.Key: Any] = [
    .font: UIFont.boldSystemFont(ofSize: 18),
    .foregroundColor: UIColor.red,
    .underlineStyle: NSUnderlineStyle.single.rawValue
]
let attributedString = NSAttributedString(string: "Стилизованный текст", attributes: attributes)
myButton.setAttributedTitle(attributedString, for: .normal)

Частая ошибка: sender vs outlet

В IBAction вы получаете параметр sender — это сама кнопка. Можно работать напрямую с ним, не используя outlet:

@IBAction func buttonTapped(_ sender: UIButton) {
    sender.setTitle("Нажато!", for: .normal)
}

Это удобно, если у вас несколько кнопок, подключенных к одному действию.

Итог

Запомните главное правило: UIButton использует setTitle(_:for:), а не прямое присвоение текста. Укажите состояние (.normal, .highlighted и т.д.) — и всё заработает. Для чтения используйте title(for:).

<<>>

Альтернативный подход: использование конфигурации (iOS 15+)

Начиная с iOS 15, Apple представила новый API для UIButton через свойство configuration. Это более современный и гибкий способ управления текстом, изображениями и стилем кнопки.

// Устанавливаем конфигурацию
var config = UIButton.Configuration.filled()
config.title = "Нажми меня"
config.baseForegroundColor = .white
config.baseBackgroundColor = .systemBlue
config.cornerStyle = .medium

let button = UIButton(configuration: config)
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)

// Меняем текст через конфигурацию
func updateTitle() {
    // Создаём новую конфигурацию на основе текущей
    var updatedConfig = button.configuration
    updatedConfig?.title = "Нажато!"
    button.configuration = updatedConfig
}

Преимущества этого подхода:

  • Единый источник правды для текста, изображения и стиля
  • Автоматическая адаптация под динамический тип шрифта
  • Упрощает поддержку тёмной темы

Важно: Если вы используете setTitle(_:for:) вместе с configuration, приоритет имеет конфигурация. Выберите один способ и придерживайтесь его, чтобы избежать путаницы.

Для iOS 14 и старше используйте классический setTitle из первого ответа. Для новых проектов, ориентированных на iOS 15+, рекомендую переходить на конфигурации — они более декларативны и удобны.