ios - 重新排序集合查看单元格 buggy

标签 ios swift collectionview batman.js

我能够让细胞四处移动,但它有问题。当您移动它们时,图片会发生变化,并且它们不会停留在您移动的位置。当您向下滚动并向后滚动时,它们会向后移动。

//
//  CollectionViewController.swift
//  1.7 Task: Displaying Sets of Data: Collection View
//
//  Created by Eric Andersen on 3/26/18.
//  Copyright © 2018 Eric Andersen. All rights reserved.
//

import UIKit

class CollectionViewController: UICollectionViewController {

    var batmanDataItems = [DataItem]()
    var jokerDataItems = [DataItem]()
    var allItems = [[DataItem]]()

    var longPressGesture: UILongPressGestureRecognizer!

    override func viewDidLoad() {
        for i in 1...29 {
            if i > 0 {
                batmanDataItems.append(DataItem(title: "Title #\(i)", kind: Kind.Batman, imageName: "bat\(i).jpg"))

            } else {
                batmanDataItems.append(DataItem(title: "Title #0\(i)", kind: Kind.Batman, imageName: "bat0\(i).jpg"))
            }
        }

        for i in 1...8 {
            if i > 0 {
                jokerDataItems.append(DataItem(title: "Another Title #\(i)", kind: Kind.Joker, imageName: "jok\(i).jpg"))
            } else {
                jokerDataItems.append(DataItem(title: "Another Title #0\(i)", kind: Kind.Joker, imageName: "jok0\(i).jpg"))
            }
        }

        allItems.append(batmanDataItems)
        allItems.append(jokerDataItems)

        super.viewDidLoad()

        let width = collectionView!.frame.width / 3
        let layout = collectionViewLayout as! UICollectionViewFlowLayout
        layout.itemSize = CGSize(width: width, height: width)

        longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongGesture(gesture:)))
        collectionView?.addGestureRecognizer(longPressGesture)


        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Register cell classes


        // Do any additional setup after loading the view.
    }


    /*
     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     // Get the new view controller using [segue destinationViewController].
     // Pass the selected object to the new view controller.
     }
     */

    // MARK: UICollectionViewDataSource

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return allItems[section].count
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! DataItemCell
        let dataItem = allItems[indexPath.section][indexPath.item]
        cell.dataItem = dataItem

        return cell
    }

    override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "SectionHeader", for: indexPath) as! DataItemHeader
        var title = ""
        if let kind = Kind(rawValue: indexPath.section) {
            title = kind.description()
        }
        sectionHeader.title = title

        return sectionHeader
    }

    override func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
        return true
    }

    override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        // print("Starting Index: \(sourceIndexPath.item)")
        // print("Ending Index: \(destinationIndexPath.item)")
    }
    // MARK: UICollectionViewDelegate


    // Uncomment this method to specify if the specified item should be highlighted during tracking
    override func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool {
        return true
    }



    // Uncomment this method to specify if the specified item should be selected
    override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
        return true
    }

    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        allItems[indexPath.section].remove(at: indexPath.row)

        self.collectionView?.performBatchUpdates({
            self.collectionView?.deleteItems(at: [indexPath])
        }) { (finished) in
            self.collectionView?.reloadItems(at: (self.collectionView?.indexPathsForVisibleItems)!)
        }

    }

    @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()
        }
    }



}

enter image description here

我是新人。我知道这很容易,但我仍在掌握窍门。感谢您的耐心等待!

最佳答案

移动行只会更新屏幕,但不会更改您的模型(向 collectionView 提供数据的数组)。然后,当单元格离开屏幕并重新打开时,它们会从未更改的数组中加载,这就是单元格返回到原来位置的原因。

您需要覆盖 func collectionView(_:moveItemAt:to:)并更新数据数组以反射(reflect)已移动的行。

override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {

    // Remove the source item from the array and store it in item
    let item = allItems[sourceIndexPath.section].remove(at: sourceIndexPath.item)

    // insert the item into the destination location
    allItems[destinationIndexPath.section].insert(item, at: destinationIndexPath.item)

}

关于ios - 重新排序集合查看单元格 buggy ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49545720/

相关文章:

ios - swift xcode 播放播放器列表中的声音文件

ios - Xcode 12.0 中是否有任何更改将 ButtonType 从 roundedRect 更改为系统?

ios - 在委托(delegate)内部访问时 IBOutlet 值为零

ios - 如何根据内容大小获取 CollectionViewCell 内容高度?

ios - 如何在不重新加载visibleCell的情况下重新加载collectionView上的数据

ios - 使用单词而不是点的自定义页面控件 - Swift

iphone - setSelected 上的自定义 UITableViewCell 和动画 :animated:

ios - 在 iOS 10.1 Xamarin(iOS) 中设置 StatusBar 样式的错误

cocoa - Swift 中 Array<Prototocol> 中对象的索引

sql - Swift 4 SQLITE 查询输出因 where 子句而失败