【问题标题】:How to dynamically constraint cell contentView's inside subViews?如何在子视图内动态约束单元格内容视图?
【发布时间】:2020-12-23 21:07:10
【问题描述】:

在collectionCell的conentView中,我想根据不同的值来约束不同高度的垂直子视图,但问题是当内容滚出屏幕时高度意外改变,然后在屏幕上回滚:

初始和正确的视图高度:

滚动离开屏幕,然后返回(视图高度因未知原因而更改):

下面是布局代码:

    let contentView = cell.contentView
    let row = indexPath.row
    
    //calculate view height: relativeHeight value
    let cellHeight = cell.frame.height
    var relativeHeight = 0.6 * cellHeight
    
    let values = [112.0, 116.0, 86.0, 95.0, 67.0, 76.0, 34.0, 43.0, 24.0, 35.0, 47.0, 66.0, 66.0, 57.0, 36.0, 64.0, 23.0, 22.0, 23.0, 22.0, 22.0, 22.0, 20.0, 23.0]
    
    let Δvalue = values.max()! - values.min()!
    
    let value = values[row]
    if Δvalue != 0 {
        let different = value - values.min()!
        let ratio = CGFloat(different / Δvalue)
        relativeHeight = ratio * relativeHeight
    }
    
    if contentView.subviews.count == 0 {
        //time label
        let timeLabel = UILabel()
        timeLabel.tag = 3
        timeLabel.textColor = self.textColor
        timeLabel.font = UIFont.boldSystemFont(ofSize: 13)
        contentView.addSubview(timeLabel)
        
        timeLabel.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            timeLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -4),
            timeLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
        ])
        
        //vertical view 
        let valueView = UIView()
        valueView.tag = 1
        valueView.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.382) //1-0.618
        
        contentView.addSubview(valueView)
        
        valueView.translatesAutoresizingMaskIntoConstraints = false
        //valueView.constraints.forEach{ $0.isActive = false }
        
        NSLayoutConstraint.activate([
            valueView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            valueView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            valueView.bottomAnchor.constraint(equalTo: timeLabel.topAnchor, constant: -4),
            valueView.heightAnchor.constraint(equalToConstant: relativeHeight)
        ])
        
        //value label
        let valueLabel = UILabel()
        valueLabel.tag = 2
        valueLabel.textColor = self.textColor
        valueLabel.font = UIFont.systemFont(ofSize: 12)
        contentView.addSubview(valueLabel)
        
        valueLabel.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            valueLabel.bottomAnchor.constraint(equalTo: valueView.topAnchor, constant: -4),
            valueLabel.centerXAnchor.constraint(equalTo: valueView.centerXAnchor)
        ])
        
    }

如何解决这样的布局约束问题?

提前非常感谢!

【问题讨论】:

  • valueView.heightAnchor.constraint(equalToConstant: relativeHeight) 你是如何计算relativeHeight 的?还有任何特殊原因在将约束添加到语句valueView.constraints.forEach{ $0.isActive = false } 之前停用约束,您是否在单元格中保留valueView 的引用?如果有现有的valueView,是否有机会不创建它?
  • 请参阅 relativeHeight 计算补充。我认为可能是约束冲突导致视图高度变化,所以我尝试先停用,然后激活。每个单元格都有自己或独立的 valueView,它不保留可供其他单元格使用的引用。
  • relativeHeight 的计算对我来说似乎没问题,因为每次执行代码时您都在分配一个新的valueView 实例,我想不需要valueView.constraints.forEach{ $0.isActive = false }。一个大问题,何时执行此代码?是cellForRow(:indexPath)还是UITableViewCell的任何生命周期方法?这样调试会很困难,能不能创建一个有问题的示例项目并在github上分享,希望能进一步检查。
  • 它在 cellForRow(:indexPath) 中。请在“github.com/steve880925/CollectionView-Bug”下载代码

标签: ios autolayout uicollectionviewcell


【解决方案1】:

我猜这个问题是因为没有valueViewheightConstraint 的引用,您在分配后尝试设置,检查contentView.subviews.count == 0。您为UICollectionViewCell 准备视图层次结构的方式可能根本不是一个好习惯。在使可重用视图出队时,必须涵盖每个条件以设置动态值。如果contentView.subviews.count == 0 失败,这里没有任何处理程序。

修复是使用子类UICollectionViewCell 来抽象CollectionViewCell: UICollectionViewCell 中所有与视图相关的任务。我添加了一个属性valueViewHeightConst,初始约束值为0.0。我在计算要设置的高度值后设置精确值。

还引入了一种缓存机制,您无需在每次单元出列时计算relativeHeight

请在https://github.com/sauvikapple/StackoverflowAnsToQ63743769查看最终项目。

这是结果

【讨论】:

    猜你喜欢
    • 2017-03-19
    • 2016-10-20
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多