iOS/UIKit
[UIKit][코드베이스] Drag and Drop Picture
- -
[참고영상]
[학습 목표]
이미지를 드래그 & 드롭하거나 드롭했을시 원래 위치로 돌아오게 만들자.
[구현 방법]
1. viewDidLoad 안쪽에 imageView와 card뷰를 만들자.
2. "DALL"이라는(혹은 다른 이름의) 이미지를 Asset안에 넣어두자.
fileprivate let imageView = UIImageView(image: UIImage(named: "DALL"))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(imageView)
imageView.contentMode = .scaleAspectFill
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 450).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 275).isActive = true
imageView.clipsToBounds = true
imageView.layer.cornerRadius = 30
let card = UIView()
imageView.addSubview(card)
card.translatesAutoresizingMaskIntoConstraints = false
card.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
card.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
card.heightAnchor.constraint(equalToConstant: 450).isActive = true
card.widthAnchor.constraint(equalToConstant: 275).isActive = true
card.backgroundColor = UIColor.blue.withAlphaComponent(0.67)
}
3. 이미지를 움직일때 동작을 시킬 handlePanGesture 함수를 만들어주자.
@objc func handlePanGestrue(gesture: UIPanGestureRecognizer) {
if gesture.state == .began {
print("began")
} else if gesture.state == .changed {
let translation = gesture.translation(in: self.view)
imageView.transform = CGAffineTransform(translationX: translation.x, y: translation.y)
} else if gesture.state == .ended {
UIView.animate(withDuration: 0.8, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 1, options: .curveEaseIn, animations: {
self.imageView.transform = .identity
})
}
}
해당 함수는 UIPanGestrueRecognizer를 이용하며 이동의 시작(began), 이동의 중간(changed), 이동의 끝(ended)의 3개의 상태 변화를 파악한다.
changed를 이용해서 이미지를 움직이게 만들고 ended를 이용해서 이미지를 원상복귀 시킨다.
CGAffineTransform 함수를 이용해서 움직이는 x와 y의 위치를 파악하자. (만일 y나 x를 0으로 둔다면 수직이나 수평으로만 움직이는 것을 볼 수가 있을 것이다.)
만일 ended 내부에 있는 내용을 지운다면 이미지가 움직인 상태 그대로 멈출 것이다.
4. viewDidLoad 내부에 카드와 imageView가 움직일수 있게 만들자.
card.isUserInteractionEnabled = false
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.handlePanGestrue)))
보면 card의 경우에는 InteractionEnabled가 false인데도 불구하고 image와 같이 움직이는 것을 확인 할 수가 있다.
이를 통해서 뷰를 움직였을때 해당 뷰 윗쪽에 있는 계층들도 같이 해당 뷰를 따라서 움직이는 것을 알 수가 있다.
[전체 코드]
import UIKit
class ViewController: UIViewController {
fileprivate let imageView = UIImageView(image: UIImage(named: "DALL"))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(imageView)
imageView.contentMode = .scaleAspectFill
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 450).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 275).isActive = true
imageView.clipsToBounds = true
imageView.layer.cornerRadius = 30
let card = UIView()
imageView.addSubview(card)
card.translatesAutoresizingMaskIntoConstraints = false
card.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
card.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
card.heightAnchor.constraint(equalToConstant: 450).isActive = true
card.widthAnchor.constraint(equalToConstant: 275).isActive = true
card.backgroundColor = UIColor.blue.withAlphaComponent(0.67)
card.isUserInteractionEnabled = false
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.handlePanGestrue)))
}
@objc func handlePanGestrue(gesture: UIPanGestureRecognizer) {
if gesture.state == .began {
print("began")
} else if gesture.state == .changed {
let translation = gesture.translation(in: self.view)
imageView.transform = CGAffineTransform(translationX: translation.x, y: translation.y)
} else if gesture.state == .ended {
UIView.animate(withDuration: 0.8, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 1, options: .curveEaseIn, animations: {
self.imageView.transform = .identity
})
}
}
}
'iOS > UIKit' 카테고리의 다른 글
[UIKit][코드 베이스] UIKit에서 Zstack 구현하기 (0) | 2022.10.13 |
---|---|
[UIKit][코드베이스] Programmatic UI - UIKit (0) | 2022.10.12 |
[UIKit] Drag & Drop CollectionView Cells (코드베이스) (0) | 2022.10.06 |
[UIKit] Simple Drawing App with PencilKit (0) | 2022.10.04 |
[Combine] MVVM Combine - Transform Input & Output (0) | 2022.10.03 |
Contents
소중한 공감 감사합니다