簡體   English   中英

在平移期間,UICollectionView單元格在各個部分之間無法正確移動

[英]UICollectionView cells are not moved correctly between sections during panning

要在UICollectionView中移動項目,我使用UILongPressGestureRecognizer。

我實現了以下手勢處理程序:

func handleLongGesture(gesture: UILongPressGestureRecognizer) {
    switch(gesture.state) {
    case UIGestureRecognizerState.Began:
        guard let selectedIndexPath = self.collectionView.indexPathForItemAtPoint(gesture.locationInView(self.collectionView)) else {break}
       collectionView.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath)
    case UIGestureRecognizerState.Changed:
        collectionView.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!))
    case UIGestureRecognizerState.Ended:
        collectionView.endInteractiveMovement()
    default:
        collectionView.cancelInteractiveMovement()
    }
}

與集合視圖委托方法moveItemAtIndexPath的正確覆蓋一起,一個部分內的移動單元格可以完美地工作。 此外,將細胞移動到其他可見區域也可以按預期工作。 但是,將單元格移動到通過平移/向下滾動變為可見的部分時會出現問題,從而導致以下錯誤(我使用Realm數據庫):

'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of items in section 0.  The number of items contained in an existing section after the update (1) must be equal to the number of items contained in that section before the update (0), plus or minus the number of items inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).'

此問題似乎與updateInteractiveMovementTargetPosition的手勢識別器跟蹤位置更改有關,因為此方法中發生錯誤。

我想updateInteractiveMovementTargetPosition直接調用集合視圖方法moveItemAtIndexPath (不通過委托),這會導致錯誤,因為Realm數據庫中的中間單元位置更改沒有更新。 還是我錯了?

是否有人知道為什么在各部分之間移動適用於可見部分,而不是在平移期間? 如何正確處理滾動/平移?

UICollectionView和UITableView API在UI狀態下進行更新並要求在數據源中進行鏡像時非常難以接受。

您需要更新Realm以反映UI狀態,以保持UICollectionView的快樂。

下面是一個Realm支持的UITableViewController示例,其中包含可重新排序的單元格,您可以根據您的UICollectionView用例進行調整:

import UIKit
import RealmSwift

class ObjectList: Object {
    let list = List<DemoObject>()
}

class DemoObject: Object {
    dynamic var title = ""
}

class TableViewController: UITableViewController {
    var items: List<DemoObject>?

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
        tableView.editing = true

        let realm = try! Realm()
        if realm.isEmpty {
            try! realm.write {
                let list = ObjectList()
                list.list.appendContentsOf(["one", "two", "three"].map {
                    DemoObject(value: [$0])
                })
                realm.add(list)
            }
        }
        items = realm.objects(ObjectList.self).first!.list
    }

    override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
        return items?.count ?? 0
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
        cell.textLabel?.text = items?[indexPath.row].title
        return cell
    }

    override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
        return .None
    }

    override func tableView(tableView: UITableView, shouldIndentWhileEditingRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        return false
    }

    override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
        guard let items = items else { return }
        try! items.realm?.write {
            let itemToMove = items[fromIndexPath.row]
            items.removeAtIndex(fromIndexPath.row)
            items.insert(itemToMove, atIndex: toIndexPath.row)
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM