Конфигурация кнопок в iOS 15
Victor
В iOS 15 компания Apple значительно обновила кнопки. Мы можем создавать и обновлять конфигурации кнопок подобно изменениям, которые Apple ввела для ячеек коллекции и таблиц в iOS 14.
Четыре основных стиля
Начиная с Xcode 13, для кнопки существует четыре основных предустановленных стиля. Когда вы перетаскиваете кнопку из библиотеки объектов в Interface Builder, она имеет обычный стиль. С помощью инспектора атрибутов выберите один из других стилей:

Если вы поддерживаете iOS 14 или более ранние версии, вам нужно изменить стиль кнопки на "По умолчанию". Затем вы можете дополнительно настроить конфигурацию кнопки в инспекторе атрибутов или в коде.
Конфигурации кнопок
Если вы создаете свои кнопки в коде, то в iOS 15 конфигурация кнопки заменяет многие старые методы и свойства UIButton: Вы можете установить конфигурацию непосредственно на кнопке:
let button = UIButton(type: .system) button.configuration = .plain() button.configuration = .gray() button.configuration = .tinted() button.configuration = .filled()
Чтобы настроить одну из предопределенных конфигураций, сначала сделайте ее копию:
var config = UIButton.Configuration.filled() config.title = "Custom Filled Button" ... button.configuration = config
Если вы перешли на действия на основе закрытия UIAction из iOS 13, передайте конфигурацию при создании кнопки:
let button = UIButton(configuration: config,
primaryAction: UIAction() { _ in
print("Go")
})
Настройка кнопки
При настройке кнопки вы изменяете конфигурацию, а не устанавливаете свойства непосредственно для кнопки. Давайте рассмотрим некоторые из вариантов.
Title и subtitle
Заголовок и подзаголовок кнопки могут быть обычным текстом или attributed strings:
var config = UIButton.Configuration.filled() config.title = "Start" config.subtitle = "Both Engines"

Если вы используете подзаголовок, вы можете изменить выравнивание по отношению к заголовку и отступы от него:
config.titleAlignment = .center config.titlePadding = 4.0

Цвета кнопок
Вы можете установить базовый цвет фона и переднего плана кнопки. Кнопка может менять эти базовые цвета в различных состояниях (например, когда она выделена):
config.baseBackgroundColor = .green config.baseForegroundColor = .black

Для большего контроля над фоном UIButton поддерживает UIBackgroundConfiguration, представленную в iOS 14 для ячеек таблиц и коллекций:
config.background.backgroundColor = .systemYellow config.background.strokeColor = .systemRed config.background.strokeWidth = 4.0

Стиль углов (cornerStyle)
Стиль углов по умолчанию - динамический. Вы также можете выбрать fixed, small, medium, large и capsule:
config.cornerStyle = .capsule

Размещение изображения
При добавлении изображения на передний план кнопки вы можете управлять отступом от заголовка, размещением (top, trailing, bottom, leading) и конфигурацией символа:
config.image = UIImage(systemName: "car", withConfiguration: UIImage.SymbolConfiguration(scale: .large)) config.imagePlacement = .trailing config.imagePadding = 8.0

Индикатор активности
Установка свойства showsActivityIndicator заменяет изображение индикатором активности:

Размер кнопки
Вы можете запросить предпочтительный размер кнопки. В Interface Builder это скрывается в инспекторе размеров:
config.buttonSize = .large

Content Insets
Content insets управляют отступами между границами кнопки и содержимым (заголовком и изображением):
config.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 20)

Configuration Update Handler
Чтобы изменить внешний вид кнопки в ответ на изменение состояния, зарегистрируйте обработчик обновления конфигурации. Например, для переключения между filled и outline, когда кнопка находится в highlighted state:
button.configurationUpdateHandler = { button in
var config = button.configuration
config?.image = button.isHighlighted ?
UIImage(systemName: "car.fill") :
UIImage(systemName: "car")
button.configuration = config
}

Чтобы расширить пример, предположим, что у меня есть свойство для автомобиля, который я хочу показать в подзаголовке кнопки:
private var range = Measurement(value: 100,
unit: UnitLength.miles)
private lazy var formatter = MeasurementFormatter()
Добавление подзаголовка к моему обработчику обновления конфигурации:
button.configurationUpdateHandler = { [unowned self] button in
var config = button.configuration
...
config?.subtitle = self.formatter.string(from: self.range)
button.configuration = config
}
Затем мы вызываем setNeedsUpdateConfiguration на кнопке при didSet для обновления подзаголовка при каждом изменении диапазона:
private var range = Measurement(value: 100,
unit: UnitLength.miles) {
didSet {
button.setNeedsUpdateConfiguration()
}
}

Для подготовки статьи использовался материал отсюда.
А про разработку можно прочитать в моём авторском канале.
