Как программно изменить текст UIButton в Swift? (iOS)
Проблема: у 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+, рекомендую переходить на конфигурации — они более декларативны и удобны.