2017-04-13 84 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

相關問題