UICollectionView.reloadData() 更改单元格顺序 | iOS 斯威夫特

Posted

技术标签:

【中文标题】UICollectionView.reloadData() 更改单元格顺序 | iOS 斯威夫特【英文标题】:UICollectionView.reloadData() changes cell order | iOS Swift 【发布时间】:2016-06-08 21:14:07 【问题描述】:

所以我正在使用一个简单的 UICollectionView,X 行 3 列,其中 X 由变量 matchesFromSelectedSession.count + 1 设置。这是我用于我的 collectionView 的委托函数:

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    return 3


func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize 
    let cellHeight = 15.0 as CGFloat
    return CGSizeMake(collectionView.bounds.size.width/3, cellHeight)


func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int 
    return matchesFromSelectedSession.count + 1


func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 
    let reuseIdentifier = "MatchCollectionViewCell"
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! MatchCollectionViewCell
    cell.matchCollectionLabel = UILabel(frame: CGRectMake(0,0,collectionView.bounds.width/3 - 3.0,15))
    cell.matchCollectionLabel.textColor = UIColor.blackColor()
    cell.systemLayoutSizeFittingSize(cell.frame.size, withHorizontalFittingPriority: UILayoutPriorityDefaultHigh, verticalFittingPriority: UILayoutPriorityDefaultLow)
    cell.matchCollectionLabel.font = UIFont(name: "Helvetica Neue", size:12)
    if indexPath.section == 0 
        switch indexPath.row 
        case 0:
            cell.matchCollectionLabel.text = "Match #"
            cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            cell.matchCollectionLabel.textAlignment = NSTextAlignment.Right
            break
        case 1:
            cell.matchCollectionLabel.text = "Record"
            cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            cell.matchCollectionLabel.textAlignment = NSTextAlignment.Center
            break
        case 2:
            cell.matchCollectionLabel.text = "Outcome"
            cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            break
        default:
            cell.matchCollectionLabel.text = ""
            cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            break
        
     else 
        switch indexPath.row 
        case 0:
            cell.matchCollectionLabel.text = "\(indexPath.section)"
            if indexPath.section%2 == 0 
                cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            
            cell.matchCollectionLabel.textAlignment = NSTextAlignment.Right
            break
        case 1:
            cell.matchCollectionLabel.text = matchesFromSelectedSession[indexPath.section - 1].matchRecord()
            if indexPath.section%2 == 0 
                cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            
            cell.matchCollectionLabel.textAlignment = NSTextAlignment.Center
            break
        case 2:
            let outcome = matchesFromSelectedSession[indexPath.section - 1].matchOutcome()
            switch outcome 
            case "W":
                cell.matchCollectionLabel.text = "Win"
                cell.matchCollectionLabel.textColor = UIColor.greenColor()
                break
            case "D":
                cell.matchCollectionLabel.text = "Draw"
                cell.matchCollectionLabel.textColor = UIColor.blueColor()
                break
            case "L":
                cell.matchCollectionLabel.text = "Loss"
                cell.matchCollectionLabel.textColor = UIColor.redColor()
                break
            default:
                cell.matchCollectionLabel.textColor = UIColor.blackColor()
                break
            
            if indexPath.section%2 == 0 
                cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            
            break
        default:
            if indexPath.section%2 == 0 
                cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            
            cell.matchCollectionLabel.text = ""
            break
        
    
    //add subview if new cell otherwise tag cell to know to reuse next time
    if cell.tag != 19 
        cell.addSubview(cell.matchCollectionLabel)
    
    cell.tag = 19
    return cell

我使用的自定义单元格,MatchCollectionViewCell,只包含一个标签,matchCollectionLabel,就是这样。我在视图的 viewDidAppear 函数中使用 self.matchCollectionView.reloadData() 来处理辅助视图更改表并解散回原始视图的情况。

我在第一次使用后标记单元格,我不会在每次 viewDidAppear 之后不断向单元格添加不必要的子视图。

表格在初始设置后看起来不错,但在调用 reloadData 后,collectionView 的单元格顺序发生了变化和混乱。如果我编辑单元格的数量,reloadData() 会更新以正确显示单元格数量的变化,但单元格的顺序仍然不正确。

这是reloadData前后的图片

http://imgur.com/wqfXqLG.png

任何帮助将不胜感激!谢谢!

【问题讨论】:

你能贴一张collectionView的前后照片吗?这可能会提供一些线索。 您每次都在创建一个新标签。如果标签不是 19,则仅将其添加为子视图,但您始终分配一个新标签。这意味着当您重用一个单元格时,您正在更新一个新标签,而不是已添加到该单元格的标签,因此您的更改不可见。底部的标签检查应该在函数的顶部,如果标签不是 19,您应该只创建一个新标签。您也可以将 cell.matchCollectionLabel 定义为可选并检查它是否为零 @DJohnson 我添加了问题的图片,但 Paulw11 提供了我需要的答案。谢谢大家! 【参考方案1】:

您每次都在创建一个新标签。如果标签不是 19,则仅将其添加为子视图,但您始终分配一个新标签。

这意味着当您重复使用一个单元格时,您正在更新一个新标签,而不是已添加到该单元格的标签,因此您的更改不可见。

您可以将标签检查移至函数顶部并使用它来控制标签的分配,或者将matchCollectionLabel 定义为可选,然后您可以检查nil

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 
    let reuseIdentifier = "MatchCollectionViewCell"
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! MatchCollectionViewCell

    if cell.matchCollectionLabel == nil 
        cell.matchCollectionLabel = UILabel(frame: CGRectMake(0,0,collectionView.bounds.width/3 - 3.0,15))
        cell.matchCollectionLabel!.textColor = UIColor.blackColor()
        cell.systemLayoutSizeFittingSize(cell.frame.size, withHorizontalFittingPriority: UILayoutPriorityDefaultHigh, verticalFittingPriority: UILayoutPriorityDefaultLow)
        cell.matchCollectionLabel!.font = UIFont(name: "Helvetica Neue", size:12)
        cell.addSubview(cell.matchCollectionLabel!)
    

    if indexPath.section == 0 
        switch indexPath.row 
        case 0:
            cell.matchCollectionLabel!.text = "Match #"
            cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            cell.matchCollectionLabel!.textAlignment = NSTextAlignment.Right
            break
        case 1:
            cell.matchCollectionLabel!.text = "Record"
            cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            cell.matchCollectionLabel!.textAlignment = NSTextAlignment.Center
            break
        case 2:
            cell.matchCollectionLabel!.text = "Outcome"
            cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            break
        default:
            cell.matchCollectionLabel!.text = ""
            cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            break
        
     else 
        switch indexPath.row 
        case 0:
            cell.matchCollectionLabel!.text = "\(indexPath.section)"
            if indexPath.section%2 == 0 
                cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            
            cell.matchCollectionLabel!.textAlignment = NSTextAlignment.Right
            break
        case 1:
            cell.matchCollectionLabel!.text = matchesFromSelectedSession[indexPath.section - 1].matchRecord()
            if indexPath.section%2 == 0 
                cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            
            cell.matchCollectionLabel!.textAlignment = NSTextAlignment.Center
            break
        case 2:
            let outcome = matchesFromSelectedSession[indexPath.section - 1].matchOutcome()
            switch outcome 
            case "W":
                cell.matchCollectionLabel!.text = "Win"
                cell.matchCollectionLabel!.textColor = UIColor.greenColor()
                break
            case "D":
                cell.matchCollectionLabel!.text = "Draw"
                cell.matchCollectionLabel!.textColor = UIColor.blueColor()
                break
            case "L":
                cell.matchCollectionLabel!.text = "Loss"
                cell.matchCollectionLabel!.textColor = UIColor.redColor()
                break
            default:
                cell.matchCollectionLabel!.textColor = UIColor.blackColor()
                break
            
            if indexPath.section%2 == 0 
                cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            
            break
        default:
            if indexPath.section%2 == 0 
                cell.backgroundColor = ImageEditor.colorWithHexString("EFEFF4")
            
            cell.matchCollectionLabel!.text = ""
            break
        
    
    return cell

【讨论】:

这很棒!我没有意识到它创造了这么多细胞!非常感谢您,也感谢您向我展示了一些示例代码。不能对此给予足够的支持:)

以上是关于UICollectionView.reloadData() 更改单元格顺序 | iOS 斯威夫特的主要内容,如果未能解决你的问题,请参考以下文章