Swift UITableViewCell可更改来自服务器的基于内容的数据

Swift UITableViewCell可更改来自服务器的基于内容的数据,swift,uitableview,autolayout,Swift,Uitableview,Autolayout,我正在努力解决这个与UITableViewCell相关的问题。我有一个子类UITableViewCell,名为applicationmessagecell,它有一些子视图、标签、图像视图等。它的顶部不依赖于状态。只需获取数据,更改标签文本和imageView的图像 然而,对于最下面的部分,对于每个进入的状态,我有完全不同的3个子类UIView。我需要在ApplicationMessageCell的底部显示相关的UIView子类。但是我找不到一个方法来做 当然,我可以为每个状态创建不同的UITa

我正在努力解决这个与
UITableViewCell
相关的问题。我有一个子类
UITableViewCell
,名为
applicationmessagecell
,它有一些子视图、标签、图像视图等。它的顶部不依赖于状态。只需获取数据,更改标签文本和imageView的图像

然而,对于最下面的部分,对于每个进入的状态,我有完全不同的3个子类
UIView
。我需要在
ApplicationMessageCell
的底部显示相关的
UIView
子类。但是我找不到一个方法来做

  • 当然,我可以为每个状态创建不同的
    UITableViewCell
    子类,但我不想走这条路,因为这只是一种情况,我还有更多
  • 我试图创建
    UIView
    的子类,在调整自身大小时,它的行为类似于
    UILabel
    。我没办法做到
  • 最后,我知道添加每个关于每个状态的
    UIView
    子类并显式显示一个/隐藏其余部分可以解决这个问题,但我相信有更好的方法来实现这一点
我没有分享任何代码,因为我认为这更多的是一个理论问题,但如果有人要求,我当然会


提前感谢。

这里有一个简单的例子

cell类有两个标签、一个堆栈视图和三个高度不同的视图(红色、绿色、蓝色),用作“显示或不显示”视图:

  • 第一个标签被约束到顶部
  • 第二个标签被约束到第一个标签的底部
  • 堆栈视图被约束到第二个标签的底部和单元格的底部(当然是contentView)
然后将三个不同高度的视图添加到堆栈视图中。根据推测,不同视图的子视图上的约束将决定它们各自的高度。对于本例,它们被设置为40、80和160

查看以下代码中的注释-它应该是非常自解释的:

class ApplicantMessageCell: UITableViewCell {
    
    let titleLabel = UILabel()
    let subLabel = UILabel()
    
    let stackView = UIStackView()
    
    let viewA = UIView()
    let viewB = UIView()
    let viewC = UIView()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    func commonInit() -> Void {
        
        [titleLabel, subLabel, stackView].forEach { v in
            v.translatesAutoresizingMaskIntoConstraints = false
            contentView.addSubview(v)
        }
        
        let g = contentView.layoutMarginsGuide

        NSLayoutConstraint.activate([
            
            // constrain titleLabel at top
            titleLabel.topAnchor.constraint(equalTo: g.topAnchor),
            titleLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor),
            titleLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor),
            
            // subLabel 8-pts below titleLabel
            subLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8.0),
            subLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor),
            subLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor),

            // stackView 8-pts below subLabel
            stackView.topAnchor.constraint(equalTo: subLabel.bottomAnchor, constant: 8.0),
            stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
            stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
            
        ])
        
        // constrain stackView bottom to bottom
        // this will avoid auto-layout complaints while the cells are configured
        let c = stackView.bottomAnchor.constraint(equalTo: g.bottomAnchor)
        c.priority = .defaultHigh
        c.isActive = true
        
        // UI element properties
        stackView.axis = .vertical
        stackView.spacing = 8
        
        titleLabel.backgroundColor = .yellow
        subLabel.backgroundColor = .cyan
        
        viewA.backgroundColor = .red
        viewB.backgroundColor = .green
        viewC.backgroundColor = .blue

        // you'll be filling the views with something to determine their heights
        //  but here we'll just set them to 40, 80 and 160 pts
        
        for (v, h) in zip([viewA, viewB, viewC], [40.0, 80.0, 160.0]) {
            stackView.addArrangedSubview(v)
            v.heightAnchor.constraint(equalToConstant: CGFloat(h)).isActive = true
        }
        
    }
    
    func fillData(_ top: String, sub: String, showViews: [Bool]) -> Void {
        titleLabel.text = top
        subLabel.text = sub
        // hide views as defined in showViews array
        for (v, b) in zip(stackView.arrangedSubviews, showViews) {
            v.isHidden = !b
        }
    }
    
}

struct ApplicationStruct {
    var title: String = ""
    var subTitle: String = ""
    var showViews: [Bool] = [true, true, true]
}

class FarukTableViewController: UITableViewController {

    var theData: [ApplicationStruct] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        for i in 0..<20 {
            // cycle through views 1, 2, 3
            let b1 = i % 3 == 0
            let b2 = i % 3 == 1
            let b3 = i % 3 == 2
            let a = [b1, b2, b3]
            let d = ApplicationStruct(title: "Title \(i)", subTitle: "", showViews: a)
            theData.append(d)
        }
        
        // just to test, set more than one view visible in a couple cells
        theData[11].showViews = [true, false, true] // red and blue
        theData[12].showViews = [false, true, true] // green and blue
        theData[13].showViews = [true, true, false] // red and green
        theData[14].showViews = [true, true, true]  // all three

        tableView.register(ApplicantMessageCell.self, forCellReuseIdentifier: "cell")
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return theData.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let c = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ApplicantMessageCell
        
        let d = theData[indexPath.row]
        
        let subStr = "showViews: " + d.showViews.description
        
        c.fillData(d.title, sub: subStr, showViews: d.showViews)
        
        return c
    }
    
}
class AppliantMessageCell:UITableViewCell{
设titleLabel=UILabel()
设subLabel=UILabel()
让stackView=UIStackView()
让viewA=UIView()
让viewB=UIView()
让viewC=UIView()
重写init(样式:UITableViewCell.CellStyle,reuseIdentifier:String?){
init(样式:style,reuseIdentifier:reuseIdentifier)
commonInit()
}
必需初始化?(编码器:NSCoder){
super.init(编码器:编码器)
commonInit()
}
func commonInit()->Void{
[标题标签,子标签,堆栈视图].forEach{v in
v、 translatesAutoresizingMaskIntoConstraints=false
contentView.addSubview(v)
}
设g=contentView.layoutMarginsGuide
NSLayoutConstraint.activate([
//在顶部约束标题标签
标题标签.topAnchor.constraint(等式:g.topAnchor),
标题标签引导锚定约束(等于:g引导锚定),
标题标签.trailingAnchor.constraint(等式:g.trailingAnchor),
//小标签标题标签下8点
子标签.topAnchor.constraint(等式:titleLabel.bottomAnchor,常量:8.0),
子标签leadingAnchor约束(等于:g.leadingAnchor),
子标签trailingAnchor.constraint(等式:g.trailingAnchor),
//stackView 8-pts位于子标签下方
stackView.topAnchor.constraint(等式:subLabel.bottomAnchor,常量:8.0),
stackView.leadingAnchor.constraint(等式:g.leadingAnchor),
stackView.trailingAnchor.constraint(等式:g.trailingAnchor),
])
//从下到下约束stackView
//这将避免在配置单元时出现自动布局投诉
设c=stackView.bottomAnchor.constraint(等式:g.bottomAnchor)
c、 优先级=.defaultHigh
c、 isActive=true
//UI元素属性
stackView.axis=.vertical
stackView.spacing=8
标题标签.背景颜色=.黄色
子标签.backgroundColor=.cyan
viewA.backgroundColor=.red
viewB.backgroundColor=.green
viewC.backgroundColor=.blue
//您将用一些东西填充视图以确定它们的高度
//但在这里,我们将它们设置为40分、80分和160分
用于拉链中的(v,h)([viewA,viewB,viewC],[40.0,80.0,160.0]){
stackView.addArrangedSubview(v)
v、 heightAnchor.constraint(equalToConstant:CGFloat(h)).isActive=true
}
}
func fillData(uu顶部:字符串,子:字符串,显示视图:[Bool])->Void{
titleLabel.text=顶部
subLabel.text=sub
//隐藏ShowView数组中定义的视图
对于zip中的(v,b)(stackView.ArrangedSubview,ShowView){
v、 伊希登=!b
}
}
}
结构应用程序结构{
变量标题:String=“”
var subTitle:String=“”
var showViews:[Bool]=[true,true,true]
}
类FarukTableViewController:UITableViewController{
变量数据:[应用程序结构]=[]
重写func viewDidLoad(){
super.viewDidLoad()
对于0..Int中的i{
返回data.count
}
重写func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
让c=tableView.dequeueReusableCell(标识符为“cell”,for:indexPath)作为!applicationMessageCell
设d=data[indexPath.row]
let subStr=“showViews:+d.showViews.description
c、 fillData(d.title,sub:subStr,showview:d.showview)
返回c
}
}
第一行显示“ViewType1”的结果第二行