Конфигурация кнопок в iOS 15

Конфигурация кнопок в 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)

Стиль углов по умолчанию - динамический. Вы также можете выбрать fixedsmallmediumlarge и 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()
  }
}

Для подготовки статьи использовался материал отсюда.

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

Report Page