简体   繁体   English

Swift:如何清除 collectionView 以便在 collectionViewCell 中重用

[英]Swift: How to clear collectionView for reuse in a collectionViewCell

I have a collectionView that is inside a collectionViewCell and the collectionView isn't getting cleared correctly when the cell is being reused.我有一个collectionView,它位于collectionViewCell 内,并且在重用单元格时collectionView 没有被正确清除。

Code:代码:

class TweetCell: UICollectionViewCell {

    lazy var mediaCollectionView: UICollectionView = {
        let size = NSCollectionLayoutSize(
            widthDimension: NSCollectionLayoutDimension.fractionalWidth(1),
            heightDimension: NSCollectionLayoutDimension.fractionalHeight(1)
        )
        
        let item = NSCollectionLayoutItem(layoutSize: size)
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: size, subitem: item, count: 1)
        let section = NSCollectionLayoutSection(group: group)
        section.interGroupSpacing = 4
        section.orthogonalScrollingBehavior = .paging
        
        let layout = UICollectionViewCompositionalLayout(section: section)
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.dataSource = self
        cv.delegate = self
        cv.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
        return cv
    }()

    var tweet: Tweet? {
        didSet {
            if let tweet = tweet {

                //Setup other UI elements
                nameLabel.text = tweet.name ?? ""
                twitterHandleLabel.text = tweet.twitterHandle ?? ""
                profileImageView.sd_setImage(with: profileImageUrl) 
            }
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    
        setupViews()
    }
 
    func setupViews() {
    
 
        let mainStack = UIStackView(arrangedSubviews: [
            userHStack,
            mediaCollectionView,
            bottomHStack
        ])
    
        mainStack.axis = .vertical
        mainStack.translatesAutoresizingMaskIntoConstraints = false
    
        addSubview(mainStack)
        mainStack.topAnchor.constraint(equalTo: topAnchor).isActive = true
        mainStack.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        mainStack.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        mainStack.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    
        //Must lower priority otherwise autolayout will complain
        heightConstraint = mediaCollectionView.heightAnchor.constraint(equalToConstant: 0)
        heightConstraint.priority = UILayoutPriority(999)
    
    }

    override func prepareForReuse() {
        super.prepareForReuse()
    
        mediaCollectionView.reloadData()
        tweet = nil
    }
} 

extension TweetCell: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource  {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return tweet?.mediaArray?.count ?? 1
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        cell.backgroundColor = .systemPink
        return cell
    }
}

//HomeController that displays the feed
class HomeController: UIViewController {

    lazy var collectionView: UICollectionView = {
        let size = NSCollectionLayoutSize(
            widthDimension: NSCollectionLayoutDimension.fractionalWidth(1),
            heightDimension: NSCollectionLayoutDimension.estimated(500)
        )
        
        let item = NSCollectionLayoutItem(layoutSize: size)
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: size, subitem: item, count: 1)
        
        let section = NSCollectionLayoutSection(group: group)
        
        let layout = UICollectionViewCompositionalLayout(section: section)
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.dataSource = self
        cv.delegate = self
        cv.register(TweetCell.self, forCellWithReuseIdentifier: "cell")
        return cv
    }()
    
    var tweets: [Tweet]?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupViews()
        fetchData()
    }
    
    func fetchData() {
        let accessToken = UserDefaults.standard.string(forKey: Constants.UserDefaults.UserAccessTokenKey) ?? ""
        let secretToken = UserDefaults.standard.string(forKey: Constants.UserDefaults.UserSecretTokenKey) ?? ""
                
        TwitterClient.shared.fetchHomeTimeline(accessToken: accessToken, secretToken: secretToken) { (tweets) in
            self.tweets = tweets
            
            DispatchQueue.main.async {
                self.collectionView.reloadData()
            }
        }
    }
    
    
    func setupViews() {

        view.addSubview(collectionView)
        collectionView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    }
    
    
}

extension HomeController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return tweets?.count ?? 0
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! TweetCell
        cell.tweet = tweets?[indexPath.item]
        return cell
    }
}

If I hard code the numberOfItemsInSection to a random integer, the mediaCollectionView displays the number of cells correctly.如果我将numberOfItemsInSection硬编码为随机 integer,则mediaCollectionView会正确显示单元格的数量。 However when set dynamically to tweet?.mediaArray?.count , the number of cells are no longer correct.但是,当动态设置为tweet?.mediaArray?.count时,单元格的数量不再正确。 I believe it is due to the reuse of the collectionViewCell as the counts of these cells starts jumping around as I scroll through the collectionView.我相信这是由于 collectionViewCell 的重用,因为当我滚动浏览 collectionView 时,这些单元格的计数开始跳跃。

How do I properly reset the collectionView inside TweetCell?如何正确重置 TweetCell 中的 collectionView?

UPDATE:更新:

Attempt 2: -尝试2: -

override func prepareForReuse() {
    
    mediaCollectionView.reloadData()
    tweet = nil
    super.prepareForReuse()
}

Above didn't quite work as well.上面的工作也不太顺利。

Hmmm.嗯。 I think you have to implement the regular protocols inside the cell and refactoring all your code.我认为您必须在单元内实现常规协议并重构所有代码。

I mean UICollectionViewDelegate (or flownDelegate) and UICollectionViewDataSource.我的意思是 UICollectionViewDelegate(或 flynDelegate)和 UICollectionViewDataSource。

class TweetCell: UICollectionViewCell,UICollectionViewDelegate,UICollectionViewDataSource {

... ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Swift 动态 CollectionView 高度:CollectionView 内 CollectionViewCell - Swift Dynamic CollectionView Height: CollectionView inside CollectionViewCell 将CollectionViewCell大小设置为外部CollectionView边界的动画-Swift - Animating a CollectionViewCell Size To Outside CollectionView Boundary - Swift iOS Swift:通过CollectionView上的按钮为CollectionViewCell元素设置动画 - iOS Swift: animating CollectionViewCell elements from a button on the CollectionView Swift CollectionViewCell 的框架与其 CollectionView 不同 - Swift CollectionViewCell has different frame than its CollectionView 如何在 swift 4 中在中心显示 CollectionViewCell - How to display CollectionViewCell in center in swift 4 iOS Swift:准备collectionView单元以供重用 - iOS Swift: Prepare collectionView cell for reuse 另一个 CollectionViewCell 内的 CollectionView - CollectionView inside another CollectionViewCell CollectionView 不包含 CollectionViewCell - CollectionView does not contain CollectionViewCell 使用PagedView时如何将CollectionViewCell的边缘固定到CollectionView - How to pin the edges of a CollectionViewCell to the CollectionView when using PagedView 如何访问嵌入在主UIViewController的父collectionViewCell中的collectionView? - How to access a collectionView that is embedded in a parent collectionViewCell in the main UIViewController?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM