서서히 옅어지는 뒷 배경... 구현해보자
지금 .gif를 보면 아시겠지만, dismiss를 하기 위해 서서히 내리면 뒷배경도 서서히 옅어져요.
너무 신기해서 한 번 구현해보기로 마음먹었습니다.!
swipe해서 dismiss하는 코드는 따로 다루진 않겠습니다.
// MARK: Properties
private var viewTranslation = CGPoint(x: 0, y: 0)
// MARK: Gesture Setting
private func setGesture() {
view.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handleDismiss)))
}
// MARK: Action
@objc
func handleDismiss(sender: UIPanGestureRecognizer) {
switch sender.state {
case .changed:
viewTranslation = sender.translation(in: view)
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
if self.viewTranslation.y >= 0 {
//background 색 바꾸는 부분
var colorAlpha = 0.3 - (self.viewTranslation.y / 1000)
if colorAlpha < 0.1 {
colorAlpha = 0.1
}
self.view.backgroundColor = UIColor.black.withAlphaComponent(colorAlpha)
// transform되는 부분
self.swipeButton.transform = CGAffineTransform(translationX: 0, y: self.viewTranslation.y)
self.backView.transform = CGAffineTransform(translationX: 0, y: self.viewTranslation.y)
}
})
case .ended:
if viewTranslation.y < 200 {
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
// 원래대로 돌아갔을 때 색이랑 위치 설정
self.view.backgroundColor = UIColor.black.withAlphaComponent(0.3)
self.swipeButton.transform = .identity
self.backView.transform = .identity
})
} else {
// 배경색 없애버리기
self.view.backgroundColor = UIColor.clear
dismiss(animated: true, completion: nil)
}
default:
break
}
}
swipe를 하기 위해선 UIPanGesture가 필요한데, PanGesture는 state를 가지고 있습니다.
그래서 해당 state를 이용해서 배경색이 변화하는 걸 구현해줬어요.
case .changed:
말그대로 변화할 때 입니다. 스와이프-ing
저는 .changed상태일 때, viewTranslation.y가 바뀌는 상태에 따라서 colorAlpha값을 조정했어요.
제가 기본 배경의 alpha값을 0.3으로 정해줬기 때문에 0.3에서 빼가는 형식으로 구현했습니다.
하지만 0.3에서 빼다보면 쉽게 0이 되더라구요.
.gif에서도 다 내려가기 전까지 은은하게 검은 투명 배경이 깔려있었기 때문에 저도 다 내려가기 전까지 은은하게 깔아두려고 0.1 미만은 그냥 0.1로 처리했어요.
그리고 view자체를 transform하게되면 배경도 같이 움직여서 의도와는 너-무 다르게 결과가 나오더라구요?
그래서 storyboard에 넣어준 버튼과 뷰를 transform하는 방식으로 구현했습니다.
case .ended:
말그대로 스와이프를 멈췄을 때 입니다.
이 때 만약 우리가 viewTranslation.y < 200 만큼 움직였다면, 제자리로 돌아가게 해줬어요.
200보다 적게 움직였다는 건 거의 찔끔 움직인거라서 혹시나 사용자가 잘못 움직였을 가능성도 있기 때문이죠.
그 이외의 경우에는 배경색을 없애버리고 dismiss시켰습니다.