iOS/UIKit
[UIKit] Drag & Drop CollectionView Cells (코드베이스)
- -
[참고영상]
[학습 목표]
Drag & Drop 기능을 이용하여서 CollectionView의 위치를 옮겨 보자!
[구현 방법]
1. 이동을 하고 옮겨지는 CollectionView를 우선 만들어보자.
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
private var collectionView: UICollectionView?
var colors: [UIColor] = [
.link,
.systemGreen,
.systemBlue,
.red,
.systemOrange,
.black,
.systemPurple,
.systemYellow,
.systemPink
]
override func viewDidLoad() {
super.viewDidLoad()
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: view.frame.size.width / 3.2, height: view.frame.size.width / 3.2)
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
collectionView?.delegate = self
collectionView?.dataSource = self
collectionView?.backgroundColor = .white
view.addSubview(collectionView!)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView?.frame = view.bounds
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return colors.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = colors[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemat indexPath: IndexPath)->CGSize {
return CGSize(width: view.frame.size.width / 3.2, height: view.frame.size.width / 3.2)
}
}
코드베이스를 이용한 collectionView 구현이다.
실행을 할 시에는 제스처는 통하지 않는 단순한 cell들이 구현된다.
2. Gesture를 이제 입력시켜주자!
@objc func handleLongPressGesture( _ gesture: UILongPressGestureRecognizer){
guard let collectionView = collectionView else{
return
}
switch gesture.state {
case .began:
guard let targetIndexPath = collectionView.indexPathForItem(at: gesture.location(in: collectionView)) else{
return
}
collectionView.beginInteractiveMovementForItem(at: targetIndexPath)
case .changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: collectionView))
case .ended:
collectionView.endInteractiveMovement()
default:
collectionView.cancelInteractiveMovement()
}
}
길게 눌렸을시 반응이 오는 handleLongPressGesture를 만들자.
해당 함수를 이용해서 시작할때와 중간 과정, 끝났을때와 취소했을때의 상태를 조절할 수가 있다.
3. 이동했을때 다른 셀들이 재배열을 하게 만드는 함수들을 만들자.
func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
return true
}
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let item = colors.remove(at: sourceIndexPath.row)
colors.insert(item, at: destinationIndexPath.row)
}
item이라는 변수를 이용해서 우리들은 cell의 위치를 바꾸는 과정을 만들 수가 있다.
4. viewDidLoad 안에 넣어서 실행이 되게 해주자.
let gesture = UILongPressGestureRecognizer(target: self,
action: #selector(handleLongPressGesture(_ :)))
collectionView?.addGestureRecognizer(gesture)
여태까지 만들었던 함수들을 사용하기 위해서 위의 두가지 구절을 viewDidLoad 안에 넣어주면 실행이 된다.
[전체 코드]
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
private var collectionView: UICollectionView?
var colors: [UIColor] = [
.link,
.systemGreen,
.systemBlue,
.red,
.systemOrange,
.black,
.systemPurple,
.systemYellow,
.systemPink
]
override func viewDidLoad() {
super.viewDidLoad()
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: view.frame.size.width / 3.2, height: view.frame.size.width / 3.2)
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
collectionView?.delegate = self
collectionView?.dataSource = self
collectionView?.backgroundColor = .white
view.addSubview(collectionView!)
let gesture = UILongPressGestureRecognizer(target: self,
action: #selector(handleLongPressGesture(_ :)))
collectionView?.addGestureRecognizer(gesture)
}
@objc func handleLongPressGesture( _ gesture: UILongPressGestureRecognizer){
guard let collectionView = collectionView else{
return
}
switch gesture.state {
case .began:
guard let targetIndexPath = collectionView.indexPathForItem(at: gesture.location(in: collectionView)) else{
return
}
collectionView.beginInteractiveMovementForItem(at: targetIndexPath)
case .changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: collectionView))
case .ended:
collectionView.endInteractiveMovement()
default:
collectionView.cancelInteractiveMovement()
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView?.frame = view.bounds
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return colors.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = colors[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemat indexPath: IndexPath)->CGSize {
return CGSize(width: view.frame.size.width / 3.2, height: view.frame.size.width / 3.2)
}
func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
return true
}
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let item = colors.remove(at: sourceIndexPath.row)
colors.insert(item, at: destinationIndexPath.row)
}
}
전반적으로 어려운 코드는 아니지만 생소한 부분이 많았다. 코드 베이스를 이용한 구현에 아직 익숙하지 않으니 익숙해질때까지 복습하자.
'iOS > UIKit' 카테고리의 다른 글
[UIKit][코드베이스] Programmatic UI - UIKit (0) | 2022.10.12 |
---|---|
[UIKit][코드베이스] Drag and Drop Picture (2) | 2022.10.07 |
[UIKit] Simple Drawing App with PencilKit (0) | 2022.10.04 |
[Combine] MVVM Combine - Transform Input & Output (0) | 2022.10.03 |
Do it! 스위프트로 아이폰 앱 만들기 (0) | 2022.03.10 |
Contents
소중한 공감 감사합니다