Connect with us

Разработка

Меняем изображений у кнопки SwiftUI при нажатии

Возможно, Apple улучшит конфигурацию кнопок, чтобы сделать это проще, но пока это лучшее, что я смог сделать.

Опубликовано

/

     
     

Как изменить изображение, которое показывает кнопка SwiftUI, во время нажатия пользователем?

Состояние кнопки

Такой элемент управления UIKit, как кнопка UIButton, имеет обычное состояние по умолчанию и дополнительные состояния, которые указывают, когда она выделена, отключена, выбрана или на ней фокус. Вы можете предоставить различные конфигурации для каждого состояния. Вы можете настроить кнопку так, чтобы она показывала другое изображение, заголовок или фон, когда пользователь прикасается к ней (выделяет). Это обеспечивает полезную визуальную обратную связь с пользователем.

Кнопки в  SwiftUI лишены многих настроек UIKit. ButtonStyleConfiguration дает вам доступ к метке кнопки, состоянию isPressed и роли кнопки (cancel или destructive).

Я хочу создать эквивалент информационной кнопки UIKit, использующей SF Symbol «info.circle»:

Меняем изображений у кнопки SwiftUI при нажатии

Когда пользователь нажимает на кнопку, я хочу, чтобы изображение переключалось на заполненный вариант символа:

Меняем изображений у кнопки SwiftUI при нажатии

Стиль нажатой кнопки

Поскольку я хочу использовать этот стиль для других кнопок, я создал стиль кнопки с нажатием, который принимает заголовок и два изображения для состояния по умолчанию и состояния нажатия:

struct PressedButtonStyle: ButtonStyle {
  let title: String
  let systemImage: String
  let pressedImage: String

  func makeBody(configuration: Configuration) -> some View {
    let imageName = configuration.isPressed ? pressedImage : systemImage
    return Label(title, systemImage: imageName)
  }
}

В методе makeBody я проверяю конфигурацию кнопки и возвращаю ярлык с правильным изображением, основанным на состоянии isPressed. Мне не нравится, что стиль игнорирует настроенную метку кнопки, но я не вижу другого способа?

Затем нужно создать мою кнопку InfoButton:

struct InfoButton: View {
  let action: () -> Void

  init(_ action: @escaping () -> Void) {
    self.action = action
  }

  var body: some View {
    Button("") {
      action()
    }
    .buttonStyle(
      PressedButtonStyle(
        title: "Info",
        systemImage: "info.circle",
        pressedImage: "info.circle.fill")
    )
    .padding()
  }
}

Использование кнопки:

InfoButton {
  // Do something
}
.labelStyle(.iconOnly)
.font(.largeTitle)

Добавление анимации

Еще одна дополнительная доработка — добавление эффекта к SF Symbol к PressedButtonStyle для увеличения масштаба изображения при нажатии:

struct PressedButtonStyle: ButtonStyle {
  let title: String
  let systemImage: String
  let pressedImage: String

  func makeBody(configuration: Configuration) -> some View {
    let imageName = configuration.isPressed ? pressedImage : systemImage
    return Label(title, systemImage: imageName)
      .symbolEffect(.scale.up, isActive: configuration.isPressed)
  }
}

Возможно, Apple улучшит конфигурацию кнопок, чтобы сделать это проще, но пока это лучшее, что я смог сделать. Если у вас есть лучший подход, дайте мне знать.

Источник

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: