Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - SwiftUI] 터치 이벤트 받는 방법(contentShape) 본문

iOS 응용 (swift)

[iOS - SwiftUI] 터치 이벤트 받는 방법(contentShape)

jake-kim 2024. 12. 10. 01:08

투명 뷰로 감싸고 터치 이벤트 받는 방법

  • 투명 뷰로 감싸는 경우?
    • 뷰를 구성하고 특정 영역을 터치 이벤트 영역으로 잡고 싶거나, 접근성을 위해서 특정 뷰로 덮어서 그 부분만 특정 접근성을 주고 싶을때, 가장 단순한 방법은 투명 뷰로 감싸서 처리
  • SwiftUI에서는 투명 뷰로 감싸기 위해서 아래처럼 사용이 가능
    • 감쌀 뷰에 overlay를 선언하고 그 위에 Color.clear를 선언하고 여기에 접근성과 tapGesture를 주어서 간편하게 뷰를 감싸는 방법이 존재
struct ContentView: View {
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            
            Text("Hello, world!")
        }
        .padding()
        .overlay { // <-
            Color.clear
                .accessibilityLabel("커스텀 접근성 입니다.")
                .onTapGesture {
                    print("tap!!")
                }
        }
    }
}

구현된 뷰

  • 하지만 Color.clear를 선언하면 터치가 동작하지 않음
    • 터치가 동작하지 않는 이유는 hit test와 연관이 있는데, alpha값이 0.01보다 작으면 hit test 대상에서 제외되며 마치 뷰가 없는 것처럼 동작하기 때문

https://developer.apple.com/documentation/uikit/uiview/hittest(_:with:)

ex) 터치를 해도, onTapGesture 클로저 부분이 실행되지 않음

터치해도 터치 이벤트 발생 x

  • 단, 색상이 clear라도 접근성은 "커스텀 접근성 입니다."라고 정상적으로 동작함

터치 이벤트 받을 수 있도록 하는 방법

  • contentShape 사용
    • contentShape란 hit testing 속성을 뷰에 적용하는 방법

  • .contentShape(Rectangle())를 추가하여 해결이 가능
struct ContentView: View {
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            
            Text("Hello, world!")
        }
        .padding()
        .overlay {
            Color.clear
                .contentShape(Rectangle()) // <-
                .accessibilityLabel("커스텀 접근성 입니다.")
                .onTapGesture {
                    print("tap!!")
                }
        }
    }
}

* 참고

- https://developer.apple.com/documentation/swiftui/view/contentshape(_:eofill:)

- https://developer.apple.com/documentation/uikit/uiview/hittest(_:with:)

Comments