UIButton 使用 diffable 数据源表现不同

问题描述

我在我的集​​合视图控制器中使用 UICollectionViewDiffableDataSource。我在单元格中有一个按钮和一个按钮被按下的次数标签。一切都按预期工作,只是当我按下更长的时间时按钮的行为有所不同。通常,只要按钮被按下,按钮就应该高亮显示,但在我实现 diffable 数据源时似乎不是这种情况。

下面的GIF是使用diffable数据源实现的结果。

https://giphy.com/gifs/YfxgpsdPGJQ7J9FHij/html5

diffable 数据源的代码

enum Section {
    case main
}
var dataSource: UICollectionViewDiffableDataSource<Section,Int>?
let posts = [1,2,3,4,5,6]
let registration = UICollectionView.CellRegistration<ViewCell,Int> { cell,indexPath,item in }

dataSource = .init(collectionView: collectionView,cellProvider: { collectionView,item -> UICollectionViewCell? in
    collectionView.dequeueConfiguredReusableCell(using: registration,for: indexPath,item: item)
 })

var snapshot = NSDiffableDataSourceSnapshot<Section,Int>()
snapshot.appendSections([.main])
snapshot.appendItems(posts,toSection: .main)
dataSource?.apply(snapshot)

func collectionView(_ collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,sizeforItemAt indexPath: IndexPath) -> CGSize {
    CGSize(width: collectionView.bounds.width,height: 140)
}

当我以传统方式执行时,即 collectionView.register,按钮表现完美。

下面的GIF是传统方式实现的结果。 (预期结果)

https://giphy.com/gifs/SwaCI9iFE16f4zBy9X/html5

以传统方式实现的代码

let reuseCellIdentifier = "cellID"

collectionView.register(CollectionViewCell.self,forCellWithReuseIdentifier: reuseCellIdentifier)

override func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
    posts.count
}

override func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
     guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseCellIdentifier,for: indexPath) as? CollectionViewCell else { return UICollectionViewCell() }
     return cell
}

func collectionView(_ collectionView: UICollectionView,height: 140)
}

两个 GIF 显示相同的结果,只是第一个 GIF 中的按钮行为不同,因为只要我按下它就应该突出显示,但奇怪的是它没有。

这是错误还是什么?关于是什么解释了这一点以及尝试什么的任何线索?

如果需要,这里是完整的源代码

import UIKit

class ViewController: UICollectionViewController,UICollectionViewDelegateFlowLayout {
    var dataSource: UICollectionViewDiffableDataSource<Section,Int>?
    let reuseCellIdentifier = "cellID"
    let posts = [1,6]
    enum Section { case main }

    init() {
        super.init(collectionViewLayout: UICollectionViewFlowLayout())
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.backgroundColor = .systemBackground
//        collectionView.register(CollectionViewCell.self,forCellWithReuseIdentifier: reuseCellIdentifier)
        let registration = UICollectionView.CellRegistration<CollectionViewCell,Int> { (cell,item) in }

        dataSource = .init(collectionView: collectionView,cellProvider: { (collectionView,item) -> UICollectionViewCell? in
            collectionView.dequeueConfiguredReusableCell(using: registration,item: item)
        })

        var snapshot = NSDiffableDataSourceSnapshot<Section,Int>()
        snapshot.appendSections([.main])
        snapshot.appendItems(posts,toSection: .main)
        dataSource?.apply(snapshot)
    }

//    override func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
//        posts.count
//    }
//
//    override func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
//        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseCellIdentifier,for: indexPath) as? CollectionViewCell else { return UICollectionViewCell() }
//        return cell
//    }

    func collectionView(_ collectionView: UICollectionView,sizeforItemAt indexPath: IndexPath) -> CGSize {
        CGSize(width: collectionView.bounds.width,height: 140)
    }
}

class CollectionViewCell: UICollectionViewCell {
    var count = 0

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .systemBackground

        let label = UILabel()
        label.text = "\(count)"
        label.translatesAutoresizingMaskIntoConstraints = false

        let button = UIButton(type: .system,primaryAction: UIAction(title: "button",handler: { [weak self] action in
            guard let self = self else { return }
            self.count += 1
            label.text = "\(self.count)"
        }))
        button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 34)
        button.setTitleColor(.systemRed,for: .normal)
        button.backgroundColor = .systemGreen
        button.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(button)
        NSLayoutConstraint.activate([
            button.topAnchor.constraint(equalTo: contentView.topAnchor),button.leadingAnchor.constraint(equalTo: contentView.leadingAnchor,constant: 32),button.trailingAnchor.constraint(equalTo: contentView.trailingAnchor,constant: -32),button.heightAnchor.constraint(equalToConstant: 80)
        ])

        contentView.addSubview(label)
        NSLayoutConstraint.activate([
            label.topAnchor.constraint(equalTo: button.bottomAnchor,constant: 8),label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor,label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor,label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
        ])
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)