안녕하세요! 후르륵짭짭 입니다.
이번에는 UIGesture 중 pan과 swipe를 이용해서 위에 애니메이션 처럼 만들어 보도록 하겠습니다.
** UIPanGestureRecongnizer란 **
UIPanGestureRecongnizer 은 "A discrete gesture recognizer that interprets panning gestures." 이렇게 정의 되어 있습니다.
즉, 움직이는 동작을 해석하는 구체적인 제스처 인식기 라는 겁니다.
developer.apple.com/documentation/uikit/uipangesturerecognizer
** UIPanGesture 스토리 보드로 만들기 **
화질이 좋지 못하지만, 아래 처럼 원하는 뷰 아래에 UIPanGesture를 넣어주고 아울렛을 연결 해주세요!
정상적으로 잘 연결이 됐는지 확인 하려면 아래 처럼 Referencing Outlet Collection을 확인해보면 됩니다.
@IBAction func panGesture(_ sender: UIPanGestureRecognizer) {
let cardView = sender.view!
let point = sender.translation(in: view)
cardView.center = CGPoint(x: view.center.x + point.x, y: view.center.y + point.y)
let fromViewCenter = cardView.center.x - view.center.x
let scale = min (100/abs(fromViewCenter), 1 )
cardView.transform = CGAffineTransform(scaleX: scale, y: scale)
if fromViewCenter > 0 {
RateImageView.image = UIImage(systemName: "sun.max")
RateImageView.tintColor = .systemRed
}
else{
RateImageView.image = UIImage(systemName: "moon.stars.fill")
RateImageView.tintColor = .systemYellow
}
RateImageView.alpha = abs( fromViewCenter ) / view.center.x
if sender.state == UIPanGestureRecognizer.State.ended {
if abs(fromViewCenter) > (view.center.x * 0.8) {
let sign = fromViewCenter / abs(fromViewCenter)
UIView.animate(withDuration: 0.3) {
cardView.center = CGPoint(x: cardView.center.x + 200 * sign, y: cardView.center.y + 80)
self.CardView.alpha = 0
}
return
}
resetCardView()
}
}
위에 처럼 코드를 구성해줍니다!!
그럼 하나씩 알아 보도록 하겠습니다.
// 움직일 뷰를 sender로 넘어온 터치된 뷰로 받습니다.
let cardView = sender.view!
//translation은 현재 전체 뷰에서 이동량을 계산해 주는 것 입니다.
let point = sender.translation(in: view)
translation에 대해서 잘 이해가 안 갈 수도 있습니다.
translation은 현재 터치한 위치에서 부터 오른쪽으로 얼마나 움직였고 만약 왼쪽으로 움직였다면, 그만큼 움직인 양을 보여줍니다.
위에 이미지 처럼 움직인 양을 보여주는 것이 translation 입니다.
그래서 이 translation을 이용하여 현재 카드 뷰의 위치를 이동시킨 겁니다.
cardView.center = CGPoint(x: view.center.x + point.x, y: view.center.y + point.y)
그리고 현재 이동량이 가운대로 부터 양이면 태양이 나오고 음수면 달이 나오도록 했습니다.
//cardView의 가운대에서 뷰의 가운데 위치를 빼면 cardView의 이동량을 알 수 있다.
let fromViewCenter = cardView.center.x - view.center.x
//그리고 이동량에 따라 처리를 다릴 해줬다.
if fromViewCenter > 0 {
RateImageView.image = UIImage(systemName: "sun.max")
RateImageView.tintColor = .systemRed
}
else{
RateImageView.image = UIImage(systemName: "moon.stars.fill")
RateImageView.tintColor = .systemYellow
}
//만약 view의 가운대 위치가 50이고 이동한 가운데 위치가 25라면 0.5가 됩니다.
//그것을 가지고 현재 달과 태양의 alpha 값을 변경 해줬습니다.
RateImageView.alpha = abs( fromViewCenter ) / view.center.x
이제 panGesture를 멈췄을 때 처리하는 방법을 알려드리겠습니다.
if sender.state == UIPanGestureRecognizer.State.ended {
if abs(fromViewCenter) > (view.center.x * 0.8) {
let sign = fromViewCenter / abs(fromViewCenter)
UIView.animate(withDuration: 0.3) {
cardView.center = CGPoint(x: cardView.center.x + 200 * sign, y: cardView.center.y + 80)
self.CardView.alpha = 0
}
return
}
resetCardView()
}
이 코드를 보면 UIPanGestureRecognizer.State,ended 라 되어 있습니다. (생각한 것이 맞습니다.^ ^)
PanGestrue를 그만 했을 때를 의미합니다. 그 외에도 정말 많은 end,began,cancel 등 많습니다.
if abs(fromViewCenter) > (view.center.x * 0.8) {
let sign = fromViewCenter / abs(fromViewCenter)
UIView.animate(withDuration: 0.3) {
cardView.center = CGPoint(x: cardView.center.x + 200 * sign, y: cardView.center.y + 80)
self.CardView.alpha = 0
}
return
}
이 코드 같은 경우는 현재 CardView의 이동량이 view.center의 80% 보다 많이 이동했으면 view를 사라지게 하는 코드 입니다.
func resetCardView(){
UIView.animate(withDuration: 0.3) {
self.CardView.center = self.view.center
self.RateImageView.alpha = 0
self.CardView.alpha = 1
self.CardView.transform = .identity
}
}
이 코드는 사라지고 나서 다시 뷰를 만들어주는 코드 입니다 ㅎㅎㅎㅎ
** UISwipeGestureRecognizer **
UISwipeGestureRecognizer는 스와이프 동작을 인식하는 겁니다.
일단 아래 처럼 SwipeGesture를 메인뷰에 넣어주시고 아울렛을 연결해주세요 (화질이 안 좋네요 ㅠㅠ)
그리고나서 SwipeGestureRecognizer를 누르면 Attribute inspector를 눌러주시고 swipe 방향을 설정해주세요
이렇게 Left 인지, Right인지 UP, Down 인지 해주셔야합니다.
@IBAction func SwipeLeft(_ sender: UISwipeGestureRecognizer) {
if sender.direction == .left {
dismiss(animated: true, completion: nil)
}
}
그리고 이렇게 sender.direction을 설정해주시고, 그때 따라 값을 넣어주시면 됩니다.
(참고로 User Interaction Enable이 true로 되어 있어야합니다.)
지금 까지 UIGesture로 Swipe와 Pan을 알아보왔습니다.
모든 것을 다루진 않았지만 UIGesture를 잘만 이용한다면 게임이나 여러가지 것들을 만들 수 잇을 것 같습니다.
모두 즐코코 하세요
** 전체 코드 **
class SecondViewController: UIViewController {
@IBOutlet weak var CardView: UIView!
@IBOutlet weak var RateImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func resetBtn(_ sender: Any) {
resetCardView()
}
@IBAction func panGesture(_ sender: UIPanGestureRecognizer) {
let cardView = sender.view!
let point = sender.translation(in: view)
cardView.center = CGPoint(x: view.center.x + point.x, y: view.center.y + point.y)
let fromViewCenter = cardView.center.x - view.center.x
let scale = min (100/abs(fromViewCenter), 1 )
cardView.transform = CGAffineTransform(scaleX: scale, y: scale)
if fromViewCenter > 0 {
RateImageView.image = UIImage(systemName: "sun.max")
RateImageView.tintColor = .systemRed
}
else{
RateImageView.image = UIImage(systemName: "moon.stars.fill")
RateImageView.tintColor = .systemYellow
}
RateImageView.alpha = abs( fromViewCenter ) / view.center.x
if sender.state == UIPanGestureRecognizer.State.ended {
if abs(fromViewCenter) > (view.center.x * 0.8) {
let sign = fromViewCenter / abs(fromViewCenter)
UIView.animate(withDuration: 0.3) {
cardView.center = CGPoint(x: cardView.center.x + 200 * sign, y: cardView.center.y + 80)
self.CardView.alpha = 0
}
return
}
resetCardView()
}
}
func resetCardView(){
UIView.animate(withDuration: 0.3) {
self.CardView.center = self.view.center
self.RateImageView.alpha = 0
self.CardView.alpha = 1
self.CardView.transform = .identity
}
}
@IBAction func SwipeLeft(_ sender: UISwipeGestureRecognizer) {
if sender.direction == .left {
dismiss(animated: true, completion: nil)
}
}
}
참고 사이트 :
www.youtube.com/watch?v=0fXR-Ksuqo4
'Xcode > IOS' 카테고리의 다른 글
IOS) NastedScrollView를 만들어 보자 (0) | 2020.11.02 |
---|---|
IOS) 복사 & 붙여넣기를 구현해보자!!! (0) | 2020.09.16 |
IOS) PageViewController로 화면전환을 만들어보자! (1) | 2020.08.16 |
IOS) UIImagePickerController에 대해서 알아보자 (0) | 2020.08.13 |
IOS) 다국어 Localized에 대해서 알아보자 (1) | 2020.08.12 |
댓글