[Swift] CollectionView는 쉽게 드래그 앤 드롭으로 이동할 수 있습니까?
소개
iOS9 이상만 지원하지만,
CollectionViewCell을 쉽게 이동할 수 있는 메서드가 있다는 것을 최근에 알았으므로,
공유합니다. (늦은)
동작 이미지
샘플 코드
먼저 샘플 코드를 참조하십시오.
CollectionView의 구현 자체는 특별한 일을하지 않습니다.
긴 탭의 제스처 부분에 주목하십시오.
ViewController.swiftimport UIKit
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
private var numbers = [Int]()
override func viewDidLoad() {
super.viewDidLoad()
numbers = loadTestData()
addEventListner()
}
//ダミーデータです
private func loadTestData() -> [Int]{
for i in 1...100 {
numbers.append(i)
}
return numbers
}
private func addEventListner() {
let longPressGesture = UILongPressGestureRecognizer(target: self,
action: #selector(self.handleLongGesture(_:)))
collectionView.addGestureRecognizer(longPressGesture)
}
//ここがポイントです
func handleLongGesture(gesture: UILongPressGestureRecognizer) {
switch(gesture.state) {
case UIGestureRecognizerState.Began:
guard let selectedIndexPath = collectionView.indexPathForItemAtPoint(gesture.locationInView(collectionView)) else {
break
}
collectionView.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath)
case UIGestureRecognizerState.Changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!))
case UIGestureRecognizerState.Ended:
collectionView.endInteractiveMovement()
default:
collectionView.cancelInteractiveMovement()
}
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numbers.count
}
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(LabelCollectionViewCell.reuseIdentifier,
forIndexPath: indexPath) as! LabelCollectionViewCell
cell.number = numbers[indexPath.item]
return cell
}
func collectionView(collectionView: UICollectionView,
moveItemAtIndexPath sourceIndexPath: NSIndexPath,
toIndexPath destinationIndexPath: NSIndexPath) {
let tempNumber = numbers.removeAtIndex(sourceIndexPath.item)
numbers.insert(tempNumber, atIndex: destinationIndexPath.item)
}
}
UILabel만의 CollectionViewCell입니다.
LabelCollectionViewCell.swiftimport UIKit
protocol ReusableView: class {}
extension ReusableView where Self: UIView {
static var reuseIdentifier: String {
return String(self)
}
}
class LabelCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var numberLabel: UILabel!
var number = 0 {
didSet {
numberLabel.text = "\(number)"
}
}
}
extension LabelCollectionViewCell: ReusableView {}
조금 해설
드래그 앤 드롭 기능은 롱 탭 제스처와 연동하여,
아래의 메소드를 호출하면 됩니다.
메소드 이름
설명
beginInteractiveMovementForItemAtIndexPath(indexPath: NSIndexPath)
이동 시작
updateInteractiveMovementTargetPosition(targetPosition: CGPoint)
이동 중
endInteractiveMovement()
이동 종료
cancelInteractiveMovement()
이동 취소
요약
iOS10의 정식 릴리스 가까이지만,
iOS9에서도 모르는 기능이 아직 있는 것 같습니다.
iOS8까지는 드래그 앤 드롭 구현이 힘들었지만,
iOS9에서는 쉽게 할 수 있게 된 것 같습니다. (늦은 2회째)
iPhone 표준 캘린더와 같은 구현을 할 수 있도록 단련하고 싶습니다.
Reference
이 문제에 관하여([Swift] CollectionView는 쉽게 드래그 앤 드롭으로 이동할 수 있습니까?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/eKushida/items/78d53d365bb69c7e7e0e
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
private var numbers = [Int]()
override func viewDidLoad() {
super.viewDidLoad()
numbers = loadTestData()
addEventListner()
}
//ダミーデータです
private func loadTestData() -> [Int]{
for i in 1...100 {
numbers.append(i)
}
return numbers
}
private func addEventListner() {
let longPressGesture = UILongPressGestureRecognizer(target: self,
action: #selector(self.handleLongGesture(_:)))
collectionView.addGestureRecognizer(longPressGesture)
}
//ここがポイントです
func handleLongGesture(gesture: UILongPressGestureRecognizer) {
switch(gesture.state) {
case UIGestureRecognizerState.Began:
guard let selectedIndexPath = collectionView.indexPathForItemAtPoint(gesture.locationInView(collectionView)) else {
break
}
collectionView.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath)
case UIGestureRecognizerState.Changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!))
case UIGestureRecognizerState.Ended:
collectionView.endInteractiveMovement()
default:
collectionView.cancelInteractiveMovement()
}
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numbers.count
}
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(LabelCollectionViewCell.reuseIdentifier,
forIndexPath: indexPath) as! LabelCollectionViewCell
cell.number = numbers[indexPath.item]
return cell
}
func collectionView(collectionView: UICollectionView,
moveItemAtIndexPath sourceIndexPath: NSIndexPath,
toIndexPath destinationIndexPath: NSIndexPath) {
let tempNumber = numbers.removeAtIndex(sourceIndexPath.item)
numbers.insert(tempNumber, atIndex: destinationIndexPath.item)
}
}
import UIKit
protocol ReusableView: class {}
extension ReusableView where Self: UIView {
static var reuseIdentifier: String {
return String(self)
}
}
class LabelCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var numberLabel: UILabel!
var number = 0 {
didSet {
numberLabel.text = "\(number)"
}
}
}
extension LabelCollectionViewCell: ReusableView {}
iOS10의 정식 릴리스 가까이지만,
iOS9에서도 모르는 기능이 아직 있는 것 같습니다.
iOS8까지는 드래그 앤 드롭 구현이 힘들었지만,
iOS9에서는 쉽게 할 수 있게 된 것 같습니다. (늦은 2회째)
iPhone 표준 캘린더와 같은 구현을 할 수 있도록 단련하고 싶습니다.
Reference
이 문제에 관하여([Swift] CollectionView는 쉽게 드래그 앤 드롭으로 이동할 수 있습니까?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/eKushida/items/78d53d365bb69c7e7e0e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)