적당한 고통은 희열이다

- 댄 브라운 '다빈치 코드' 중에서

초보 iOS 개발자의 일상/이슈모음집

iOS 18 버튼 터치 이벤트 간헐적으로 씹히는 이슈 (feat. simultaneousGesture)

hongssup_ 2025. 3. 19. 18:59
반응형

새로운 기능을 추가하고 심사를 올렸는데,

전혀 다른 곳에서 리젝이 났다. 

 

Guideline 2.1 - Performance - App Completeness

Bug description: the 'xxx' button was unresponsive

 

잘 작동되던 버튼이 진짜로 안눌리네;;

근데 이상하다. 

잘 눌릴 때도 있고 안눌릴 때도 있고, 한 화면이 전체 다 안눌리는 것도 아니고 

어떤 건 눌리고 어떤 건 안눌리고 그것도 다 랜덤이고

도대체 이게 뭐람 🤷🏻‍♀️

 

iOS 17 이하 버전에서는 잘 되는 것 같고,

iOS 18 이상에서 간헐적으로 발생하는 문제인 것 같은데..

 

포럼에도 다음과 같은 이슈가 올라왔더라

Button Responsiveness Problems in SwiftUI Apps After Upgrading to iOS 18

https://developer.apple.com/forums/thread/765559

 

Button Responsiveness Problems in … | Apple Developer Forums

I am also encountering this issue, when I press the button the Animation does not respond, I have to long press the button for it to work, however the functions inside the button does fire Once clicked. its annoying as it is working as normal on iOS 17.

developer.apple.com

 

원인

.onTapGesture 와 Button action 을 동시에 사용할 경우 버튼 터치 액션이 씹혀서 발생할 수 있는 문제인 것 같다.

SwiftUI에서는 터치 이벤트를 하나의 뷰에서만 처리하려고 하기 때문에,

Button 내부나 Button을 감싸는 뷰에 onTapGesture를 추가하면 제스처 충돌이 발생할 수 있다.

다음과 같은 경우에, 버튼을 클릭해도 onTapGesture만 실행될 수 있다. 

VStack {
    Button(action: {
        print("Button 클릭")
    }) {
        Text("Tap me")
    }
}
.onTapGesture {
    print("onTapGesture 실행")
}

 

 

해결 방법

.onTapGesture 대신에 .simultaneousGesture 를 사용하면 Button과 onTapGesture가 동시에 잘 실행된다.

문제가 된 화면에서 textField 를 사용하고 있어, 부모 뷰에서 화면 터치 시 키패드가 사라지도록 다음과 같이 설정 해주고 있었다.

.onTapGesture {
    hideKeyboard()
}

해당 화면 내에 버튼을 누를 경우, 이거랑 물려서 간헐적으로 씹히는 문제가 발생하는 듯

 

대신에 .simultaneousGesture 를 사용하면 문제 없이 버튼도 잘 동작하더라

.simultaneousGesture(TapGesture().onEnded {
    hideKeyboard()
})

 

 

더 알아보기

simultaneousGesture

: Attaches a gesture to the view to process simultaneously with gestures defined by the view.

 

기존 제스처가 방해받지 않고 함께 실행되도록 도와준다.

Text("Tap")
    .onTapGesture {
        print("onTapGesture")
    }
    .simultaneousGesture(TapGesture().onEnded {
        print("simultaneousGesture")
    })

// simultaneousGesture
// onTapGesture

 

728x90
반응형