질문
iOS 버전의 Android 앱을 만들고 있는데 사용자가 처음 눌렀을 때 하나의 작업을 수행 한 다음 사용자가 button 누르기를 중지하면 하나의 작업을 수행하는 button을 만들어야합니다. Java에서는 다음 코드를 사용하여이 작업을 수행했습니다.
someButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Do first task
} else if (event.getAction() == MotionEvent.ACTION_UP) {
// Do second task
}
return true;
}
});
SwiftUI button을 사용하여 어떻게 할 수 있습니까? 이 답변 을 찾았습니다. ACTION_DOWN 동작을 얻는 방법을 알려주지 만 ACTION_UP 및 ACTION_DOWN이 모두 필요하기 때문에이 접근 방식이 작동할지 확신 할 수 없습니다.
답변1
다음은 뷰 수정 자로서의 대체 (더 신뢰할 수있는) 솔루션이므로 상태 업데이트를 통해 다른 뷰에 영향을주지 않는 뷰에 연결할 수 있습니다.
Xcode 11.4 / iOS 13.4로 테스트되었습니다.
struct DemoTouchesHandling: View {
var body: some View {
VStack {
Text("Tap Me!").font(Font.system(size: 24).bold().smallCaps())
}
.frame(width: 200, height: 200)
.background(Color.red)
.modifier(TouchUpDownHandler(downAction: {print("> Down")},
upAction: {print("< Up")}))
}
}
struct TouchUpDownHandler: ViewModifier {
var downAction: (() -> Void)?
var upAction: (() -> Void)?
enum TouchState {
case inactive
case down
}
@GestureState private var gestureState: TouchState = .inactive // initial & reset value
func body(content: Content) -> some View {
content
.gesture(DragGesture(minimumDistance: 0)
.updating($gestureState, body: { (value, state, transaction) in
switch state {
case .inactive:
state = .down
self.downAction?()
case .down: break
}
})
.onEnded { value in
self.upAction?()
}
)
}
}
답변2
DragGesture를 사용할 수 있습니다.
struct ContentView: View {
@State private var index = 0
var body: some View {
let gesture = DragGesture(minimumDistance: 0, coordinateSpace: .local).onChanged({
if self.index == 0 {
print("Down: \($0)")
self.index = 1
}
}).onEnded({
if self.index == 1 {
print("Up: \($0)")
self.index = 0
}
})
return Rectangle().frame(width: 120, height: 60).gesture(gesture)
}
}
출처 : https://stackoverflow.com/questions/62462814/swiftui-button-action-like-android-action-down-and-action-up