Swift CollectionViewCell显示子视图,未添加

vwkv1x7d  于 2023-03-22  发布在  Swift
关注(0)|答案(3)|浏览(147)

我有一个collectionView,它返回20个单元格。单元格从API获取它们的信息。如果dates == true,则应该添加/显示calendarImageVieweventDatesLabel,否则不应该。测试打印显示为dates==true的单元格,而不显示为dates==false的单元格。单元格非常大,因此,您在iPhone 7上只能看到两个单元格,要查看其他单元格,您必须向下滚动。如果带有dates==false的单元格位于第一个单元格内,则不会显示calendarImageVieweventDatesLabel(应该如此),但如果带有dates==false的单元格更靠下,它仍然会显示(虽然它不应该),即使测试打印没有显示,这意味着,视图甚至没有添加到单元格中。这怎么可能?bannerView也是一样的。但是我完全没有问题,即使它写得完全一样。

class HomeCell: UICollectionViewCell {
    
    func configure(with homeEvent: HomeEvent) {
        //configures the content of subviews with variables from homeEvent, which is the result of api request
        setupViews()
    }
    
    override func prepareForReuse() {
        //resets the variables for reuse
    }
    
    //here I defined all the labels, imageViews and so on...
    
    weak var homeControllerDelegate: HomeControllerDelegate?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    func setupViews() {
        addSubview(eventImageView)
        addSubview(genreLabel)
        if discount == 1 {
            addSubview(fixDiscountLabel)
        }
        else {
            addSubview(variableDiscountLabel)
        }
        addSubview(eventTitleLabel)
        addSubview(eventSubTitleLabel)
        if dates == true {
            print("test")
            addSubview(calendarImageView)
            addSubview(eventDatesLabel)
        }
        if banner == true {
            addSubview(bannerView)
            bannerView.addSubview(bannerLabelNormal)
            bannerView.addSubview(bannerLabelBold)
        }
        
        //here i set the constraints

        }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = eventCollectionView.dequeueReusableCell(withReuseIdentifier: homeCellId, for: indexPath) as? HomeCell
            else {
                return UICollectionViewCell()
        }
        let event = homeEvents[indexPath.item] //homeEvents is an Array of Data for each cell. So every Element in this Array contains the variables needed to set the cells content, like dates, banner, ...
        cell.configure(with: event)
        cell.backgroundColor = UIColor(displayP3Red: 245/255, green: 245/255, blue: 245/255, alpha: 1)
        cell.layer.borderColor = UIColor(displayP3Red: 233/255, green: 233/255, blue: 233/255, alpha: 1).cgColor
        cell.layer.borderWidth = 1
        cell.layer.cornerRadius = 2
        cell.homeControllerDelegate = self
        return cell
    }
mm9b1k5b

mm9b1k5b1#

问题可能是由于单元格是可重用的,所以尝试删除prepareForReuse()方法中的所有子视图。

eni9jsuy

eni9jsuy2#

您还应该根据子视图是否在视图层次结构中,根据数据来删除子视图。正如其他人所说,集合视图单元格被重用。如果在索引0处有一个单元格,其中日期为true,并且您添加了calendarImageView和eventDatesLabel,那么当该单元格在屏幕外时,它将在另一个索引处重用,假设index为10。因此,当它在index为10时被重用时,您之前添加的视图仍然会在那里,您必须管理它们。因此,您可以通过执行以下操作来解决这个问题:

func setupViews() {
    addSubview(eventImageView)
    addSubview(genreLabel)
    if discount == 1 {
        addSubview(fixDiscountLabel)
    }
    else {
        addSubview(variableDiscountLabel)
    }
    addSubview(eventTitleLabel)
    addSubview(eventSubTitleLabel)
    if dates == true {
        print("test")
        addSubview(calendarImageView)
        addSubview(eventDatesLabel)
    } else {
        if subviews.contains(calendarImageView) {
            calendarImageView.removeFromSupeview()
        }

        if subviews.contains(eventDatesLabel) {
            eventDatesLabel.removeFromSuperview()
        }
    }
    if banner == true {
        addSubview(bannerView)
        bannerView.addSubview(bannerLabelNormal)
        bannerView.addSubview(bannerLabelBold)
    } else {
        if subviews.contains(bannerView) {
            bannerView.removeFromSuperview()
        }
    }
}

但老实说,这段代码有点乱,有太多的逻辑的东西,可以简化与分离。我个人会建议作出两个不同的细胞(一个有你的日历视图,一个有你的横幅视图),把它们都注册到你的集合视图,然后基于你的对象把你真正需要的那个出队。这样每个单元格就只有一个集合布局,并且您不必管理单元,因为它们被重复使用。

tag5nh1u

tag5nh1u3#

在setupViews方法中一次性添加所有子视图,然后显示/隐藏所需条件的视图。

override init(frame: CGRect) {
    super.init(frame: frame)
    addSubview(eventImageView)
    addSubview(genreLabel)
    addSubview(fixDiscountLabel)
    addSubview(variableDiscountLabel)
    addSubview(eventTitleLabel)
    addSubview(eventSubTitleLabel)
    addSubview(calendarImageView)
    addSubview(eventDatesLabel)
    addSubview(bannerView)
    bannerView.addSubview(bannerLabelNormal)
    bannerView.addSubview(bannerLabelBold)
}

private func hideAllViews(){
    eventImageView.isHidden = true
    genreLabel.isHidden = true
    eventTitleLabel.isHidden = true
    eventSubTitleLabel.isHidden = true
    fixDiscountLabel.isHidden = true
    variableDiscountLabel.isHidden = true
    calendarImageView.isHidden = true
    eventDatesLabel.isHidden = true
    bannerView.isHidden = true
}

func setupViews() {
    hideAllViews()
    if discount == 1 {
        fixDiscountLabel.isHidden = false
    }
    else {
        variableDiscountLabel.isHidden = false
    }
    if dates == true {
        print("test")

        calendarImageView.isHidden = false
        eventDatesLabel.isHidden = false

    }
    if banner == true {
        bannerView.isHidden = false
    }

    //here i set the constraints

}

相关问题