일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- tableView
- 애니메이션
- 클린 코드
- Refactoring
- SWIFT
- combine
- clean architecture
- MVVM
- ribs
- Xcode
- 리펙토링
- uiscrollview
- RxCocoa
- 스위프트
- uitableview
- collectionview
- ios
- 리팩토링
- Observable
- rxswift
- 리펙터링
- Protocol
- Clean Code
- Human interface guide
- map
- swift documentation
- UITextView
- HIG
- swiftUI
- UICollectionView
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 15. event의 원리 (hitTest, point, Responder Chain, Touch event) 본문
[iOS - swift] 15. event의 원리 (hitTest, point, Responder Chain, Touch event)
jake-kim 2020. 6. 6. 11:071. hitTest(_:with:), point(inside:with:)
- 이벤트 발생한 뷰 탐색 :
Pre-Order Depth First Traversal Algorithm 사용 (UIWindow부터 시작하며, 최근에 추가된 view먼저 탐색)
- UIWindow를 First Responder라고함(탐색의 시작점이 UIWindow이므로)
- 이벤트가 발생한 뷰를 찾는 것
self.view.addSubview(viewA)
self.view.addSubview(viewB)
self.view.addSubview(viewC)
1) 뷰의 최상위인 UIWindow가 hitTest(_:with:)호출 -> point(inside:with)로 터치 이벤트가 발생한 곳이 UIWindow내부인지 체크 -> true -> subView도 이어서 탐색
2) MainView역시 hitTest(_:with:)메소드를 통해서 1)번과 같은 작업 -> 깊이 순서에 의해 viewC를 가장 먼저 탐색(sibling관계에서는 가장 나중에 추가된 노드를 먼저 방문)
3) viewC에서 hitTest(_:with:)는 nil반환, point(inside:with:)는 false반환 -> viewB탐색
4) sibling관계에 의해서 viewB.2먼저 탐색 -> view B.1탐색
2. hitTest(_:with:), point(inside:with:) 사용하여 문제 해결하기
button이 투명한 view밑에 존재 할 때, 투명한 view를 눌러도 이 버튼에 이벤트가 발생하게끔 하는 방법?
- 투명한 view를 정의한 클래스에서 override를 이용하여 false를 반환하게끔 함
1) point(inside:with:)를 이용한 방법
- false반환
class CustomTransparentView: UIView {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return false
}
}
2) hitTest(_:with:)를 이용한 방법
- 투명한 뷰(자기 자신인 경우 nil반환)
class CustomTransparentView: UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
var hitTestView = super.hitTest(point, with: event)
if hitTestView == self { // 1.
hitTestView = nil
}
return hitTestView
}
}
class ViewController: UIViewController {
@IBOutlet weak var transparentView: CustomTransparentView!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func buttonDidTapped(_ sender: UIButton) {
print("Button Did Tapped")
}
}
3. UIResponder
이벤트를 처리하는 클래스 (이것을 상속받아서 UIView, UIViewContoller, UIWindow탄생, 이것들은 UIResponder메소드들을 재정이)
func touchesBegan(Set<UITouch>, with: UIEvent?)와 같은 메소드 재정의하여 사용
4. UIEvent
이벤트가 발생했을 때 그 이벤트에 해당한는 객체로 변환 후 UIResponder객체에게 전달
- 같은 이벤트에 대한 객체는 재사용
5. UITouch
터치 이벤트 발생시, 이벤트 객체와 동시에 터치에 관한 정보를 담는 객체
* 정보
- 터치가 발생한 윈도우나 뷰
- 터치가 발생한 좌표 : func location(in view: UIView?) -> CGPoint
- 터치의 반지름
- 터치 강조(3D touch)
- 터치 횟수
- 터치한 시점
참조 : developer.apple.com/documentation/uikit/uitouch
'iOS 기본 (swift)' 카테고리의 다른 글
[iOS - swift] 17. status bar 글씨 색깔 지정하기 (0) | 2020.08.16 |
---|---|
[iOS - swift] 16. notificationCenter (1) | 2020.07.11 |
[iOS - swift] 14. frame과 bounds (0) | 2020.06.04 |
[iOS - swift] 13. 컬렉션 뷰(Collection View) (0) | 2020.05.23 |
[iOS - swift] 12. 오토 레이아웃(auto layout) - storyboard (0) | 2020.04.04 |