Lou*_*uis 4 uicollectionview uicollectionviewcell swift ios11
我想在我的 UICollectionView 中重新排列我的单元格。但是当我放下我的项目时,会调用“cellForItemAt”方法,这将导致单元格闪烁(见下图)。
我应该怎么做才能避免这种行为?
预先感谢您的帮助。
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
private let cellIdentifier = "cell"
private let cells = [""]
private var longPressGesture: UILongPressGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongGesture(gesture:)))
collectionView.addGestureRecognizer(longPressGesture)
}
//Selectors
@objc func handleLongGesture(gesture: UILongPressGestureRecognizer) {
switch(gesture.state) {
case .began:
guard let selectedIndexPath = collectionView.indexPathForItem(at: gesture.location(in: collectionView)) else {
break
}
collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
case .changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!))
case .ended:
collectionView.endInteractiveMovement()
default:
collectionView.cancelInteractiveMovement()
}
}
}
// MARK: - UICollectionViewDataSource
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
return true
}
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
}
}
// MARK: - UICollectionViewDelegateFlowLayout
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100, height: 100)
}
}
Run Code Online (Sandbox Code Playgroud)
您需要在perfomBatchUpdates中调用endInteractiveMovement。
但是每当endInteractiveMovement触发时,就会调用cellForRow。所以单元格将被刷新并添加新单元格(检查随机颜色扩展)。为了确保这一点,您需要将 selectedCell 保存在变量中。并在调用endInteractiveMovement时返回该单元格。
在 ViewController 中声明 currentCell
var isEnded: Bool = true
var currentCell: UICollectionViewCell? = nil
Run Code Online (Sandbox Code Playgroud)
手势开始时将所选单元格存储在变量中并在performBatchUpdates 中调用endInteractiveMovement。
因此,您的 handleLongGesture 函数如下所示:
//Selectors
@objc func handleLongGesture(gesture: UILongPressGestureRecognizer) {
switch(gesture.state) {
case .began:
guard let selectedIndexPath = collectionView.indexPathForItem(at: gesture.location(in: collectionView)) else {
break
}
isEnded = false
//store selected cell in currentCell variable
currentCell = collectionView.cellForItem(at: selectedIndexPath)
collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
case .changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!))
case .ended:
isEnded = true
collectionView.performBatchUpdates({
self.collectionView.endInteractiveMovement()
}) { (result) in
self.currentCell = nil
}
default:
isEnded = true
collectionView.cancelInteractiveMovement()
}
}
Run Code Online (Sandbox Code Playgroud)
还需要改变cellForRow
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if currentCell != nil && isEnded {
return currentCell!
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath)
cell.backgroundColor = .random
return cell
}
}
Run Code Online (Sandbox Code Playgroud)
提示
使用随机颜色扩展进行更好的测试
extension UIColor {
public class var random: UIColor {
return UIColor(red: CGFloat(drand48()), green: CGFloat(drand48()), blue: CGFloat(drand48()), alpha: 1.0)
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
如果您有多个部分。让我们取数组的数组
var data: [[String]] = [["1","2"],
["1","2","3","4","5","6","7"],
["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"]]
Run Code Online (Sandbox Code Playgroud)
那么重新排序时需要维护数据
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
print("\(sourceIndexPath) -> \(destinationIndexPath)")
let movedItem = data[sourceIndexPath.section][sourceIndexPath.item]
data[sourceIndexPath.section].remove(at: sourceIndexPath.item)
data[destinationIndexPath.section].insert(movedItem, at: destinationIndexPath.item)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2951 次 |
最近记录: |