상황
- 모달로 뷰를 하나 띄웠을 때 아래로 끌어당겨 모달을 해제하려고 함
- 이때 잡아 당길 경우 모달로 띄워진 뷰가 아래로 끌어내려지면서 뒤에는 이전 뷰가 보임
- 터치를 끝냈을때 (손을 떼었을 때 ) 100~200포인트로 설정하여 그 이하는 다시 모달 뷰가 화면을 덮고 그 이상은 dismiss 함
방법
- PanGestureRecognizer를 이용함
- 최초 터치 시작점을 설정하고, 상태값이 변할 경우 y 값만큼 프레임을 내려 뷰를 끌어 당김
- 터치가 끝났을 때 (손을 떼었을때) 최초 터치 시작점에서 마지막 지점까지 y 값의 변화정도를 계산하여 150 보다 클 경우 화면을 내리고(모달을 해지하고) 그 이하일 경우 다시 모달 뷰로 화면을 덮음
과정
- 스토리보드에서 모달을 세그웨이로 지정할 경우, 스토리보드 상에서 세컨드 뷰 컨트롤러의 Presenstation 항목을 Full Screen이 아닌 Over Full Screen으로 변경함( 화면을 끌어당겼을 때 첫번째 뷰가 그 밑에 깔림)
- 만약 코드 상에서 performSegue 등으로 화면을 전환할 경우
- 또는 이처럼 모달을 띄울 경우 guard let modalToThirdView = self.storyboard?.instantiateViewController(withIdentifier: "ThirdView") else { return }
- awakeFromNib에서 모달스타일을 overFullScreen으로 변경해 줌
내용
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 initialTouchPoint = CGPoint(x: 0, y: 0) | |
override func awakeFromNib() { | |
super.awakeFromNib() | |
self.modalPresentationStyle = UIModalPresentationStyle.overFullScreen | |
// self.modalTransitionStyle = .crossDissolve | |
} | |
func setPanGesture() { | |
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panGestureDismiss(_:))) | |
self.view.addGestureRecognizer(panGesture) | |
} | |
@objc func panGestureDismiss(_ sender: UIPanGestureRecognizer) { | |
let touchPoint = sender.location(in: self.view.window) | |
if sender.state == .began { | |
initialTouchPoint = touchPoint | |
} else if sender.state == .changed { | |
if touchPoint.y - initialTouchPoint.y > 0 { | |
self.view.frame = CGRect(x: 0, y: touchPoint.y - initialTouchPoint.y, width: self.view.frame.width, height: self.view.frame.height) | |
} | |
} else if sender.state == .ended || sender.state == .cancelled { | |
if touchPoint.y - initialTouchPoint.y > 200 { | |
self.dismiss(animated: true, completion: nil) | |
} else { | |
UIView.animate(withDuration: 0.3) { | |
self.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height) | |
} | |
} | |
} | |
} |
참고: 1.
화면