Как обрабатывать события касания экрана с SwiftUI?

При работе с UIKit я работал в UIView или в UIViewController.

func touchesBegan (_ touch: Set, с событием: UIEvent?)

Как обрабатывать сенсорные события с SwiftUI?

1 ответ

Проще всего добавить DragGesture. Проверять, выписываться DragGesture.Value чтобы понять, какая информация у вас есть.

Circle()
    .gesture(
        DragGesture(minimumDistance: 5, coordinateSpace: .global)
            .onChanged { value in
              self.dragLocation = value.location
            }
            .onEnded { _ in
              self.dragLocation = .zero
            }
    )

Вы можете использовать minimumDistance: 0 для того, чтобы иметь жест, который начинает обновляться немедленно, аналогично touchesBegan(...) в UIKit.

В качестве другого способа у нас есть способ создать настраиваемую кнопку. SwiftUI предоставляет ButtonStyle, PrimitiveButtonStyle и другие.

https://developer.apple.com/documentation/swiftui/buttonstyle

Фактически, Button не создает метку самостоятельно, у Button есть Style и делегирует создание метки Style.

Итак, Стиль имеет makeBodyметод, и мы можем получить объект конфигурации. Этот объект имеет метку, переданную извне иisPressed флаг.

isPressed будут изменены события touchDown и touchUpInside.

Я создал собственный стиль кнопки. Это добавляет наложение, когда к компоненту прикасаются.

https://www.notion.so/muukii/Create-custom-highlight-component-Like-subclassing-UIControl-a4e231ffa3624dfda96141a2f60588f1

Образец кода

struct OverlayButton<Content: View>: View {

  private let content: Content

  init(
    @ViewBuilder _ content: () -> Content
  ) {
    self.content = content()
  }

  var body: some View {
    Button(action: {}) { content }
      .buttonStyle(_ButtonStyle())    
  }

  private struct _ButtonStyle: ButtonStyle {

    func makeBody(configuration: Self.Configuration) -> AnyView {
      if configuration.isPressed {
        return AnyView(
          configuration.label
            .background(Color(white: 0.96))
        )
      } else {
        return AnyView(
          configuration.label
            .background(Color(white: 1, opacity: 0.0001))
        )
      }
    }
  }

}

Я надеюсь, что это будет ваша идея.

Другие вопросы по тегам