상황
- 테이블뷰나 웹뷰처럼 스크롤뷰가 작동하는 경우 아래로 당겨서 뷰를 해제하려고 함 (테이블 뷰는 스크롤뷰를 상속받았고, WKWebView는 scrollView가 프로퍼티로 존재함)
방법
- UIPanGestureRecognizer를 이용함
- 중복되는 제스처를 처리하기 위해 UIGestureRecognizerDelegate를 채택 후 위임
내용
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var isTrackingPanLocation = false | |
func setPanGesture() { | |
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(closePopUpViewWithPanGesture(_:))) | |
tableView.addGestureRecognizer(panGesture) | |
panGesture.minimumNumberOfTouches = 1 | |
panGesture.maximumNumberOfTouches = 1 | |
panGesture.delegate = self | |
} | |
@objc func closePopUpViewWithPanGesture(_ sender: UIPanGestureRecognizer) { | |
if sender.state == .began { | |
print("bb") | |
sender.setTranslation(CGPoint.zero, in: tableView) | |
isTrackingPanLocation = true | |
} else if sender.state != .ended && sender.state != .cancelled && sender.state != .failed && isTrackingPanLocation { | |
let panOffset = sender.translation(in: tableView) | |
let eligiblePanOffset = panOffset.y > 200 | |
if eligiblePanOffset { | |
sender.isEnabled = false | |
sender.isEnabled = true | |
UIView.animate(withDuration: 0.6) { | |
self.popUpConstraint.constant = 1200 | |
self.view.layoutIfNeeded() | |
} | |
} | |
if panOffset.y < 0 { | |
isTrackingPanLocation = false | |
} | |
} else { | |
isTrackingPanLocation = false | |
} | |
} | |
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { | |
return true | |
} |
추가확인사항
- sender.isEnabled = false , sender.isEnabled = true 이처럼 불리언 값을 한번 변경해주지 않으면 해당 위치에 로그가 연속적으로 찍힘
- 웹뷰일 때는 웹뷰의 스크롤뷰 프로퍼티로 접근함 if recognizer.state == .began && webView.scrollView.contentOffset.y == 0 { (…)}
- 뷰가 사라지는 시점이 터치를 끝낸 시점이 아니라 애니메이션 효과가 도중에 발생함
참고: 1