在 CollectionView 中的单元格之间拖放不起作用,iOS、PanGestureRecognizer 和 Swift3
Drag and drop between cells in CollectionView doesn't work, iOS, PanGestureRecognizer and Swift3
我尝试创建具有 2 行和 2 列的集合视图,并在单元格之间进行简单的拖放操作。我会 post 我的控制器的 collectionView() 和 panGestureAction() 是什么样子的。
当我将手势识别器添加到故事中时,我将其放在可重复使用的单元格上。
问题是当我尝试拖放时,只有最后一个单元格可以引发事件,并且我看到了控制台日志("began" 和 "ended")。
如果我注释行 cell.contentView.addGestureRecognizer(recognizer),只有第一个单元格会引发事件。
我该怎么办,我的所有单元格都在记录消息(能够识别拖放)?
@IBOutlet weak var recognizer: UIPanGestureRecognizer!
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) ->
UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReusable, for: indexPath) as? CellCollectionViewCell else {
fatalError("The dequeued cell is not an instance of CellCollectionViewCell.")
}
cell.contentView.addGestureRecognizer(recognizer)
// Configure the cell
cell.valueLabel?.text = String(100);
cell.layer.borderWidth = 5.0
cell.layer.borderColor = UIColor.red.cgColor
cells.append(cell);
return cells[cells.count-1];
}
@IBAction func panGestureAction(_ sender: UIPanGestureRecognizer) {
if recognizer.state == UIGestureRecognizerState.began {
print("began");
}
if recognizer.state == UIGestureRecognizerState.ended {
print("ended");
}
}
更新:
import UIKit
class GridControllerCollectionViewController: UICollectionViewController, UIGestureRecognizerDelegate {
private let cellReusable = "CellCollectionViewCell"
fileprivate let numberOfColumns = 2
fileprivate let numberOfRows = 4
fileprivate var gesture: UILongPressGestureRecognizer?
@IBOutlet var collectionViewOutlet: UICollectionView!
fileprivate var cells = [CellCollectionViewCell]()
override func viewDidLoad() {
super.viewDidLoad()
gesture = UILongPressGestureRecognizer(target: self, action: #selector(panGestureAction(_:)))
gesture?.minimumPressDuration = 0.5
gesture?.delegate = self
//have tried with first line, second, and with both
collectionViewOutlet.addGestureRecognizer(gesture!)
collectionView?.addGestureRecognizer(gesture!)
print("gesture delegate is assigned!")
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return numberOfRows
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numberOfColumns
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReusable, for: indexPath) as? CellCollectionViewCell else {
fatalError("The dequeued cell is not an instance of CellCollectionViewCell.")
}
// Configure the cell
cell.valueLabel?.text = String(100);
cell.layer.borderWidth = 5.0
cell.layer.borderColor = UIColor.red.cgColor
cells.append(cell);
return cells[cells.count-1];
}
func panGestureAction(_ sender: UILongPressGestureRecognizer) {
print("panGestureAction was reached!");
// if gesture?.state == UIGestureRecognizerState.began {
// print("began");
// }
//
// if gesture?.state == UIGestureRecognizerState.ended {
// print("ended");
// }
switch sender.state {
case .began:
print("began")
case .changed:
print("changed")
case .ended:
print("ended")
default:
collectionView?.cancelInteractiveMovement()
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive press: UIPress) -> Bool {
return true
}
override func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
return true
}
}
不要将手势添加到单元格。它必须添加到您的 collectionView
gesture = UILongPressGestureRecognizer(target: self, action: #selector(panGestureAction(_:)))
gesture.minimumPressDuration = 0.5
gesture.delegate = self
collectionView.addGestureRecognizer(gesture)
实现手势委托方法
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive press: UIPress) -> Bool {
return true
}
重要:实现集合视图数据源方法
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
//
}
最后,实现您的平移手势动作
func panGestureAction(_ sender: UILongPressGestureRecognizer) {
switch sender.state {
case .began:
guard let indexPath = collectionView.indexPathForItem(at: sender.location(in: collectionView)) else {
return
}
collectionView.beginInteractiveMovementForItem(at: indexPath)
case .changed:
collectionView.updateInteractiveMovementTargetPosition(sender.location(in: collectionView))
case .ended:
collectionView.endInteractiveMovement()
default:
collectionView.cancelInteractiveMovement()
}
}
我尝试创建具有 2 行和 2 列的集合视图,并在单元格之间进行简单的拖放操作。我会 post 我的控制器的 collectionView() 和 panGestureAction() 是什么样子的。 当我将手势识别器添加到故事中时,我将其放在可重复使用的单元格上。
问题是当我尝试拖放时,只有最后一个单元格可以引发事件,并且我看到了控制台日志("began" 和 "ended")。 如果我注释行 cell.contentView.addGestureRecognizer(recognizer),只有第一个单元格会引发事件。
我该怎么办,我的所有单元格都在记录消息(能够识别拖放)?
@IBOutlet weak var recognizer: UIPanGestureRecognizer!
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) ->
UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReusable, for: indexPath) as? CellCollectionViewCell else {
fatalError("The dequeued cell is not an instance of CellCollectionViewCell.")
}
cell.contentView.addGestureRecognizer(recognizer)
// Configure the cell
cell.valueLabel?.text = String(100);
cell.layer.borderWidth = 5.0
cell.layer.borderColor = UIColor.red.cgColor
cells.append(cell);
return cells[cells.count-1];
}
@IBAction func panGestureAction(_ sender: UIPanGestureRecognizer) {
if recognizer.state == UIGestureRecognizerState.began {
print("began");
}
if recognizer.state == UIGestureRecognizerState.ended {
print("ended");
}
}
更新:
import UIKit
class GridControllerCollectionViewController: UICollectionViewController, UIGestureRecognizerDelegate {
private let cellReusable = "CellCollectionViewCell"
fileprivate let numberOfColumns = 2
fileprivate let numberOfRows = 4
fileprivate var gesture: UILongPressGestureRecognizer?
@IBOutlet var collectionViewOutlet: UICollectionView!
fileprivate var cells = [CellCollectionViewCell]()
override func viewDidLoad() {
super.viewDidLoad()
gesture = UILongPressGestureRecognizer(target: self, action: #selector(panGestureAction(_:)))
gesture?.minimumPressDuration = 0.5
gesture?.delegate = self
//have tried with first line, second, and with both
collectionViewOutlet.addGestureRecognizer(gesture!)
collectionView?.addGestureRecognizer(gesture!)
print("gesture delegate is assigned!")
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return numberOfRows
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numberOfColumns
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReusable, for: indexPath) as? CellCollectionViewCell else {
fatalError("The dequeued cell is not an instance of CellCollectionViewCell.")
}
// Configure the cell
cell.valueLabel?.text = String(100);
cell.layer.borderWidth = 5.0
cell.layer.borderColor = UIColor.red.cgColor
cells.append(cell);
return cells[cells.count-1];
}
func panGestureAction(_ sender: UILongPressGestureRecognizer) {
print("panGestureAction was reached!");
// if gesture?.state == UIGestureRecognizerState.began {
// print("began");
// }
//
// if gesture?.state == UIGestureRecognizerState.ended {
// print("ended");
// }
switch sender.state {
case .began:
print("began")
case .changed:
print("changed")
case .ended:
print("ended")
default:
collectionView?.cancelInteractiveMovement()
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive press: UIPress) -> Bool {
return true
}
override func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
return true
}
}
不要将手势添加到单元格。它必须添加到您的 collectionView
gesture = UILongPressGestureRecognizer(target: self, action: #selector(panGestureAction(_:)))
gesture.minimumPressDuration = 0.5
gesture.delegate = self
collectionView.addGestureRecognizer(gesture)
实现手势委托方法
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive press: UIPress) -> Bool {
return true
}
重要:实现集合视图数据源方法
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
//
}
最后,实现您的平移手势动作
func panGestureAction(_ sender: UILongPressGestureRecognizer) {
switch sender.state {
case .began:
guard let indexPath = collectionView.indexPathForItem(at: sender.location(in: collectionView)) else {
return
}
collectionView.beginInteractiveMovementForItem(at: indexPath)
case .changed:
collectionView.updateInteractiveMovementTargetPosition(sender.location(in: collectionView))
case .ended:
collectionView.endInteractiveMovement()
default:
collectionView.cancelInteractiveMovement()
}
}