2017-04-13 28 views
1

我在UIViewcontroller的CollectionView中遇到问题。 我从JSON中获取数据,并且在特殊情况下单元格似乎没有被正确重用,而且我认为我设置CollectionView的方式有些问题。Swift CollectionView可重复使用的单元格注册

一个概述:

MyCollectionViewCell.swift

import UIKit 

class MyCollectionViewCell: UICollectionViewCell { 

    @IBOutlet weak var bottomLabel: UILabel! 
    @IBOutlet weak var topLabel: UILabel! 

} 

正如你可以看到我在小区的两个标签。我的viewController的 及零部件:

import UIKit 

private let reuseIdentifier = "colcel" 

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { 

    override func viewDidLoad() { 

     super.viewDidLoad() 

     // Register cell classes 
     //collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier) 

     //SOME JSON PARSING HAPPENS HERE 

     collectionView.delegate = self 
     collectionView.dataSource = self 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let colcel = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! MyCollectionViewCell 

     colcel.contentView.layer.cornerRadius = 5.0 
     colcel.layer.shadowColor = UIColor.darkGray.cgColor 
     colcel.layer.shadowOffset = CGSize(width: 12, height: 4.0) 
     colcel.layer.shadowRadius = 12.0 
     colcel.layer.masksToBounds = false 

     return colcel 
    } 
} 

现在,当我尝试使用,例如:

colcel.topLabel.text = "someText" 

我得到:

fatal error: unexpectedly found nil while unwrapping an Optional value

当我删除了collectionview.register在它的工作原理viewDidLoad() 。 现在的问题是我的register行动没有必要或者它是错的?

//编辑。

我的手机重新排序:

viewDidLoad()是这样的:

//Long Pressure for reordering 
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.handleLongGesture)) 
self.collectionView.addGestureRecognizer(longPressGesture) 

这是相应的功能:

func handleLongGesture(gesture: UILongPressGestureRecognizer) { 

    switch(gesture.state) { 

    case UIGestureRecognizerState.began: 
     guard let selectedIndexPath = self.collectionView.indexPathForItem(at: gesture.location(in: self.collectionView)) else { 
      break 
     } 
     collectionView.beginInteractiveMovementForItem(at: selectedIndexPath) 
    case UIGestureRecognizerState.changed: 
     collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!)) 
    case UIGestureRecognizerState.ended: 
     collectionView.endInteractiveMovement() 
    default: 
     collectionView.cancelInteractiveMovement() 
    } 
} 

,我有这样的功能:

func collectionView(_ collectionView: UICollectionView, 
        moveItemAt sourceIndexPath: IndexPath, 
        to destinationIndexPath: IndexPath) 
{ 
    // Update data model to reflect the change 
    let temp = devArray[sourceIndexPath.row] 
    devArray[sourceIndexPath.row] = devArray[destinationIndexPath.row] 
    devArray[destinationIndexPath.row] = temp 
} 

当我运行

self.collectionView.reloadData() 

有时位置跳

+1

您确定您的topLabel已正确连接为iboutlet吗? – MaksTheAwesome

+0

检查“topLabel”插座是否连接正确。 – PGDev

+0

我确定它是,当我删除注册它的作品,我看到故事板中的连接 – theslash

回答

1

如果你设计你的故事板带具有相应基类的原型单元格,则不应该也是register类。故事板原型单元为您完成所有这些工作。

手动注册类的唯一时间是当您以编程方式创建单元格时。在这种情况下,您应该删除原型单元格,但是您的自定义类必须自己创建子视图并以编程方式连接插座(不再是@IBOutlet引用)。

就您为什么要使用原型单元与以编程方式创建单元的原因而言,使用原型单元要容易得多。你必须编写更少的代码。如果你使用单元格原型,故事板就可以非常优雅地完成所有这些,所以我没有看到老派和注册课程以及手动创建单元格的好处。这是我们在原型单元之前的习惯。但是使用故事板与编程创建的单元格不应该影响单元重用逻辑。

你说:

... in special conditions the cells don't seem to be reused properly.

你应该告诉我们在什么情况下,细胞不重用。值得注意的是,当滚动速度非常快时,单元格在滚动视图后不会立即重用。在重用之前有一点点滞后。如果那是你看到那种行为的场景,那么,是的,我对这种行为并不感到惊讶。如果那不是你看到它没有成功出列/重新使用单元格的地方,那么分享有关您何时何地看到此行为的详细信息。


关于你单独重新排序问题,collectionView(_:moveItemAt:to:)被交换的源和目标。但你想要的是removeinsert

override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { 
    let value = devArray.remove(at: sourceIndexPath.item) 
    devArray.insert(value, at: destinationIndexPath.item) 
} 

因为你换,有问题的一个细胞看起来很好(所以一切正常,当你完成你的拖累),但所有其他细胞的IN-之间将是错误的。直到您重新加载收藏视图和/或滚动然后返回,您才会看到。通过做removeinsert,相反,模型应该保持同步。

+0

我有点复杂,但我会尝试解释:一个例子:我有一个函数重新排序collectionView中的单元格,但有时当我重新加载视图一些细胞在他们的位置跳跃。第二个示例:当来自JSON I解析的值为Null和我的警戒语句跳入时,它会显示一个emty单元格,但是当我重新加载视图时,我在此单元格中有另一个单元格的内容 – theslash

+0

我在上面编辑过,因此您可以阅读它更好... – theslash

+0

好吧我认为问题是我的重新排序功能,单元格不是“跳跃”他们正在重新排列,它们后面的数组命令是错误的 – theslash

0

请UICollectionViewCell酒店办理入住手续定制类, 确保值是MyCollectionViewCell - >ScreenShot

+0

这是已经好了,我认为罗布有答案 – theslash

相关问题