CollectionView 单元格在进入编辑模式时不一致地显示复选框

CollectionView cells inconsistently showing checkbox when entering editing mode

提问人:Aditya Vyavahare 提问时间:11/17/2023 最后编辑:Aditya Vyavahare 更新时间:11/18/2023 访问量:40

问:

进入编辑模式时,我的 UICollectionView 遇到了问题。问题是,当我向下滚动时,有些单元格会出现复选框,而另一些则没有。但是,我希望所有单元格在编辑模式下始终显示复选框。

其他上下文:

  • 我正在为我的 UICollectionView 使用自定义布局。
  • 我已经实现了自定义单元格(在本例中为 MailListCell)。
  • 当我在编辑模式下向下滚动集合视图时,会出现此问题。

预期行为:在编辑模式下,集合视图中的所有单元格都应始终显示复选框,无论它们是否可见。

override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: animated)
        
        if editing {
            // Enable multi-selection, show checkboxes, etc.
            navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelEditing))
            
            //shift the list to right
//            collectionViewLeadingConstraint?.constant = 50
            
            // Show the checkboxes and move labels to right
                    for indexPath in mailListCollectionView.indexPathsForVisibleItems {
                        if let cell = mailListCollectionView.cellForItem(at: indexPath) as? MailListCell {
                            cell.moveLabelsToRight()
//                            cell.roundCheckbox.isHidden = false
//                            cell.animateCheckboxAppearance()
                        }
                    }
            mailListCollectionView.allowsMultipleSelection = true
        } else {
            // Disable multi-selection, hide checkboxes, etc.
            navigationItem.rightBarButtonItem = editButtonItem
            
            //bring the list back to original position
//            collectionViewLeadingConstraint?.constant = 0
            
                    for indexPath in mailListCollectionView.indexPathsForVisibleItems {
                        if let cell = mailListCollectionView.cellForItem(at: indexPath) as? MailListCell {
                            cell.moveLabelsToOriginalPosition()
//                            cell.roundCheckbox.isHidden = true
                        }
                    }
        }
        
        // need to call layoutIfNeeded to apply the constraint changes
            UIView.animate(withDuration: 0.3) {
                self.view.layoutIfNeeded()
            }
    }
    @objc func cancelEditing() {
        // Implement any logic needed when the user cancels the editing mode.
        // For example, deselect any selected cells, hide checkboxes, etc.
        
        setEditing(false, animated: true)
        mailListCollectionView.allowsSelection = false
    }

以下是进入和退出编辑模式时在屏幕上发生变化的功能。

extension MailListCell {
    func moveLabelsToRight() {
        senderLeadingConstraint?.constant = 50
        subjectLeadingConstraint?.constant = 50
        dateLeadingConstraint?.constant = 50
        separatorLeadingConstraint?.constant = 50
        roundCheckboxLeadingConstraint?.constant = 10
        
        // Change alpha value to create a fading effect
        UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseInOut, animations: {
                    self.roundCheckbox.alpha = 1
                }, completion: nil)
    }

    func moveLabelsToOriginalPosition() {
        senderLeadingConstraint?.constant = 16
        subjectLeadingConstraint?.constant = 16
        dateLeadingConstraint?.constant = 16
        separatorLeadingConstraint?.constant = 16
        roundCheckboxLeadingConstraint?.constant = -20
        
        // Change alpha value to create a fading effect
        UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseInOut, animations: {
                    self.roundCheckbox.alpha = 0
                }, completion: nil)
    }
}

有关如何确保在编辑模式下保持一致的复选框可见性的任何见解或建议将不胜感激。

更新代码:

    override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: animated)
        
        if editing {
            isEditingMode = true
            // Enable multi-selection, show checkboxes, etc.
            navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelEditing))
            
            //shift the list to right
//            collectionViewLeadingConstraint?.constant = 50
            
            // Show the checkboxes and move labels to right
                    for indexPath in mailListCollectionView.indexPathsForVisibleItems {
                        if let cell = mailListCollectionView.cellForItem(at: indexPath) as? MailListCell {
                            cell.moveLabelsToRight()
//                            cell.roundCheckbox.isHidden = false
//                            cell.animateCheckboxAppearance()
                        }
                    }
            mailListCollectionView.allowsMultipleSelection = true
        } else {
            isEditingMode = false
            // Disable multi-selection, hide checkboxes, etc.
            navigationItem.rightBarButtonItem = editButtonItem
            
            //bring the list back to original position
//            collectionViewLeadingConstraint?.constant = 0
            
                    for indexPath in mailListCollectionView.indexPathsForVisibleItems {
                        if let cell = mailListCollectionView.cellForItem(at: indexPath) as? MailListCell {
                            cell.moveLabelsToOriginalPosition()
//                            cell.roundCheckbox.isHidden = true
                        }
                    }
        }
        
        // need to call layoutIfNeeded to apply the constraint changes
            UIView.animate(withDuration: 0.3) {
                self.view.layoutIfNeeded()
            }
    }

        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! MailListCell
        
        if isEditingMode {
                cell.moveLabelsToRight()
            } else {
                cell.moveLabelsToOriginalPosition()
            }
        
        cell.senderLabel.text = "some sender"
        cell.subjectLabel.text = "some subject"
        cell.dateLabel.text = "dd/mm/yyyy"

        return cell
    }
iOS Swift UIColictionView UIKit的

评论

2赞 Paulw11 11/17/2023
检查您的代码。当 cels 被重用时,它需要正确设置单元格。cellForItem

答:

1赞 son 11/17/2023 #1

您应该按照@Paulw11在他的评论中所说的方式处理数据源。我假设您将有一个启用编辑模式的功能,例如:cellForItem

func startEditing() {
    ...
    isEditingMode = true
    mailListCollectionView.allowsMultipleSelection = true
    mailListCollectionView.reloadData()
}

然后在功能中:cellForItem

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = ... as! MailListCell
    if isEditingMode {
        cell.moveLabelsToRight()
    } else {
        cell.moveLabelsToOriginalPosition()
    }
    return cell
}

评论

0赞 Aditya Vyavahare 11/18/2023
我按照建议的解决方案实施。我注意到一个新的问题链接,我在上面的问题中添加了更新的代码。
0赞 son 11/18/2023
另外,也从功能中删除。在另一个方法中处理工具栏操作,而不是重写 setEditing。cell.removeLabel...setEditing