动画应用快照时 UICollectionView 附件会滞后,除非 .disclosureIndicator() 也是附件

问题描述 投票:0回答:1

请运行以下 UIKit 应用程序。

它显示具有组合布局(列表布局)和可区分数据源的集合视图。

import UIKit

class ViewController: UIViewController {
    var bool = false {
        didSet {
            var snapshot = dataSource.snapshot()
            snapshot.reconfigureItems(snapshot.itemIdentifiers)
            dataSource.apply(snapshot, animatingDifferences: true)
        }
    }
    
    var collectionView: UICollectionView!
    
    var dataSource: UICollectionViewDiffableDataSource<String, String>!
    
    var snapshot: NSDiffableDataSourceSnapshot<String, String> {
        var snapshot = NSDiffableDataSourceSnapshot<String, String>()
        snapshot.appendSections(["section"])
        snapshot.appendItems(["id"])
        return snapshot
    }

    override func viewDidLoad() {
        super.viewDidLoad()
                        
        configureHierarchy()
        configureDataSource()
    }
    
    func configureHierarchy() {
        collectionView = .init(frame: view.bounds, collectionViewLayout: createLayout())
        view.addSubview(collectionView)
        collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    }
    
    func createLayout() -> UICollectionViewLayout {
        let configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
        return UICollectionViewCompositionalLayout.list(using: configuration)
    }
    
    func configureDataSource() {
        let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { [weak self] cell, indexPath, itemIdentifier in
            guard let self else { return }
            
            let _switch = UISwitch()
            cell.accessories = [
                .customView(configuration: .init(
                    customView: _switch,
                    placement: .trailing())
                ),
//                .disclosureIndicator()
            ]
            _switch.isOn = bool
            _switch.addTarget(self, action: #selector(toggleBool), for: .valueChanged)
        }
        
        dataSource = .init(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
            collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: itemIdentifier)
        }
        
        dataSource.apply(self.snapshot, animatingDifferences: false)
    }
    
    @objc func toggleBool() {
        bool.toggle()
    }
}

当您点击开关时,它会滞后。

如果取消注释

.disclosureIndicator()
并点击开关,它不会滞后。

如何在单元格中没有披露指示器的情况下使开关不会滞后?

注意:虽然它可以解决问题,但我不想在类级别声明开关,因为我不想在我真实的视图控制器级别声明所有控件,这可能会很多。应用程序。

uikit uicollectionviewcompositionallayout uicollectionviewdiffabledatasource
1个回答
0
投票

制作自定义单元格:

class SwitchCell: UICollectionViewListCell {
    let _switch = UISwitch()

    override init(frame: CGRect) {
        super.init(frame: frame)
        
        accessories = [
            .customView(configuration: .init(
                customView: _switch,
                placement: .trailing())
            )
        ]
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

并相应地编辑

cellRegistration

let cellRegistration = UICollectionView.CellRegistration<SwitchCell, String> { [weak self] cell, indexPath, itemIdentifier in
    guard let self else { return }
    
    cell._switch.isOn = bool
    cell._switch.addTarget(self, action: #selector(toggleBool), for: .valueChanged)
}
© www.soinside.com 2019 - 2024. All rights reserved.