Ios 使用约束将UIView添加到TableViewCell中的ContentView

Ios 使用约束将UIView添加到TableViewCell中的ContentView,ios,Ios,我正在尝试使用约束将单元格添加到UITableView。你知道怎么做吗。以下仅给出: 并表示:UIView的高度不明确 您知道如何使用约束将UIView添加到ContextView吗?请注意约束中的固定高度 import UIKit class ViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() // Do any addi

我正在尝试使用约束将单元格添加到UITableView。你知道怎么做吗。以下仅给出:

并表示:UIView的高度不明确

您知道如何使用约束将UIView添加到ContextView吗?请注意约束中的固定高度

import UIKit

class ViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier:"Cell")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")

        if cell == nil {
            cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
        }

        let view = UIView(frame: cell!.frame)
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor.orange

        let constraintTop = NSLayoutConstraint(item: cell!.contentView,
                                               attribute: NSLayoutAttribute.top,
                                               relatedBy: NSLayoutRelation.equal,
                                               toItem: view,
                                               attribute: NSLayoutAttribute.top,
                                               multiplier: 1,
                                               constant: 0)

        let constraintLeading = NSLayoutConstraint(item: cell!.contentView,
                                                   attribute: NSLayoutAttribute.leading,
                                                   relatedBy: NSLayoutRelation.equal,
                                                   toItem: view,
                                                   attribute: NSLayoutAttribute.leading,
                                                   multiplier: 1,
                                                   constant: 0)

        let constraintTrailing = NSLayoutConstraint(item: cell!.contentView,
                                                    attribute: NSLayoutAttribute.trailing,
                                                    relatedBy: NSLayoutRelation.equal,
                                                    toItem: view,
                                                    attribute: NSLayoutAttribute.trailing,
                                                    multiplier: 1,
                                                    constant: 0)

        let constraintHeight = NSLayoutConstraint(item: cell!.contentView,
                                                  attribute: NSLayoutAttribute.height,
                                                  relatedBy: NSLayoutRelation.equal,
                                                  toItem: nil,
                                                  attribute: NSLayoutAttribute.height,
                                                  multiplier: 1, constant: 50) // << Note fixed height

        view.translatesAutoresizingMaskIntoConstraints = false

        cell?.contentView.addSubview(view)
        cell?.contentView.addConstraints([constraintTop, constraintLeading, constraintTrailing, constraintHeight])

        return cell!
    }


}

第四个约束是将固定高度应用于contentView。相反,您想要的是固定contentView的底部边缘和自定义的
视图
(就像您对前导/顶部/尾部所做的那样),并将恒定高度约束应用于
视图
,而不是
contentView
contentView
只是适应它的子视图,而不是直接告诉它它的高度

此外,在
viewDidLoad
,您将希望设置
tableView.rowHeight=UITableViewAutomaticDimension
,因为您是通过约束计算高度的

import UIKit

class ViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier:"Cell")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")

        if cell == nil {
            cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
        }

        let view = UIView(frame: cell!.frame)
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor.orange

        let constraintTop = NSLayoutConstraint(item: cell!.contentView,
                                               attribute: NSLayoutAttribute.top,
                                               relatedBy: NSLayoutRelation.equal,
                                               toItem: view,
                                               attribute: NSLayoutAttribute.top,
                                               multiplier: 1,
                                               constant: 0)

        let constraintLeading = NSLayoutConstraint(item: cell!.contentView,
                                                   attribute: NSLayoutAttribute.leading,
                                                   relatedBy: NSLayoutRelation.equal,
                                                   toItem: view,
                                                   attribute: NSLayoutAttribute.leading,
                                                   multiplier: 1,
                                                   constant: 0)

        let constraintTrailing = NSLayoutConstraint(item: cell!.contentView,
                                                    attribute: NSLayoutAttribute.trailing,
                                                    relatedBy: NSLayoutRelation.equal,
                                                    toItem: view,
                                                    attribute: NSLayoutAttribute.trailing,
                                                    multiplier: 1,
                                                    constant: 0)

        let constraintHeight = NSLayoutConstraint(item: cell!.contentView,
                                                  attribute: NSLayoutAttribute.height,
                                                  relatedBy: NSLayoutRelation.equal,
                                                  toItem: nil,
                                                  attribute: NSLayoutAttribute.height,
                                                  multiplier: 1, constant: 50) // << Note fixed height

        view.translatesAutoresizingMaskIntoConstraints = false

        cell?.contentView.addSubview(view)
        cell?.contentView.addConstraints([constraintTop, constraintLeading, constraintTrailing, constraintHeight])

        return cell!
    }


}

此外,您还将遇到问题,因为此代码位于
cellForRow
中。每次屏幕上出现新单元格时,都会调用此函数,这意味着当您滚动时,将重复使用相同的视图,并添加重复的额外视图。我建议您将
UITableViewCell
子类化,并将此代码放入它的
init
您的第四个约束是将固定高度应用于contentView。相反,您想要的是固定contentView的底部边缘和自定义的
视图
(就像您对前导/顶部/尾部所做的那样),并将恒定高度约束应用于
视图
,而不是
contentView
contentView
只是适应它的子视图,而不是直接告诉它它的高度

此外,在
viewdiload
中,您需要设置
tableView.rowHeight=UITableViewAutomaticDimension
,因为您是通过约束计算高度的

import UIKit

class ViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier:"Cell")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")

        if cell == nil {
            cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
        }

        let view = UIView(frame: cell!.frame)
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor.orange

        let constraintTop = NSLayoutConstraint(item: cell!.contentView,
                                               attribute: NSLayoutAttribute.top,
                                               relatedBy: NSLayoutRelation.equal,
                                               toItem: view,
                                               attribute: NSLayoutAttribute.top,
                                               multiplier: 1,
                                               constant: 0)

        let constraintLeading = NSLayoutConstraint(item: cell!.contentView,
                                                   attribute: NSLayoutAttribute.leading,
                                                   relatedBy: NSLayoutRelation.equal,
                                                   toItem: view,
                                                   attribute: NSLayoutAttribute.leading,
                                                   multiplier: 1,
                                                   constant: 0)

        let constraintTrailing = NSLayoutConstraint(item: cell!.contentView,
                                                    attribute: NSLayoutAttribute.trailing,
                                                    relatedBy: NSLayoutRelation.equal,
                                                    toItem: view,
                                                    attribute: NSLayoutAttribute.trailing,
                                                    multiplier: 1,
                                                    constant: 0)

        let constraintHeight = NSLayoutConstraint(item: cell!.contentView,
                                                  attribute: NSLayoutAttribute.height,
                                                  relatedBy: NSLayoutRelation.equal,
                                                  toItem: nil,
                                                  attribute: NSLayoutAttribute.height,
                                                  multiplier: 1, constant: 50) // << Note fixed height

        view.translatesAutoresizingMaskIntoConstraints = false

        cell?.contentView.addSubview(view)
        cell?.contentView.addConstraints([constraintTop, constraintLeading, constraintTrailing, constraintHeight])

        return cell!
    }


}

此外,您还将遇到问题,因为此代码位于
cellForRow
中。每次屏幕上出现新单元格时,都会调用此函数,这意味着当您滚动时,将重复使用相同的视图,并添加重复的额外视图。我建议您将
UITableViewCell
子类化,并将此代码放入它的
init
好的,解决方案是:读取“输出”

把事情搞得一团糟:

单元格?.contentView.TranslatesAutoResizengMaskintoConstraints=false


删除这一行,它就会工作。

好的,解决方案是:读取“输出”

把事情搞得一团糟:

单元格?.contentView.TranslatesAutoResizengMaskintoConstraints=false


删除这一行,它就会工作。

你做错了几件事

首先,要向后设置约束。您想将新的
视图
约束到
内容视图

let constraintTop = NSLayoutConstraint(item: view,  // constrain this view
                           attribute: NSLayoutAttribute.top,
                           relatedBy: NSLayoutRelation.equal,
                           toItem: cell?.contentView,  // to this view
                           attribute: NSLayoutAttribute.top,
                           multiplier: 1,
                           constant: 0)
第二,不要这样做:

cell?.contentView.translatesAutoresizingMaskIntoConstraints = false
第三,每次重用单元时,您的代码都会添加一个新的“橙色视图”。在自定义单元格类的init部分添加子视图要好得多,但如果要在
cellForRow
中添加子视图,请先检查它是否已经存在:

    if cell.contentView.subviews.count == 0 {
        // no, so add it here

        let view = UIView()

        // continue with view setup
第四,您可能会发现以这种方式添加约束更容易/更符合逻辑/更清晰/etc:

cell.contentView.addSubview(view)

view.topAnchor.constraint(equalTo: cell.contentView.topAnchor, constant: 0.0).isActive = true
view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor, constant: 0.0).isActive = true
view.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor, constant: 0.0).isActive = true
view.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor, constant: 0.0).isActive = true
而且。。。由于您已注册一个单元类以供重用,因此此格式将为您提供一个有效的单元:

    // instead of this
    //var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
    //if cell == nil {
    //  cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
    //}

    // better method
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

下面是完整的功能:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    // have we already added the subview?
    if cell.contentView.subviews.count == 0 {
        // no, so add it here

        let view = UIView()

        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor.orange

        cell.contentView.addSubview(view)

        view.topAnchor.constraint(equalTo: cell.contentView.topAnchor, constant: 0.0).isActive = true
        view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor, constant: 0.0).isActive = true
        view.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor, constant: 0.0).isActive = true
        view.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor, constant: 0.0).isActive = true

    }

    return cell
}

你做错了几件事

首先,要向后设置约束。您想将新的
视图
约束到
内容视图

let constraintTop = NSLayoutConstraint(item: view,  // constrain this view
                           attribute: NSLayoutAttribute.top,
                           relatedBy: NSLayoutRelation.equal,
                           toItem: cell?.contentView,  // to this view
                           attribute: NSLayoutAttribute.top,
                           multiplier: 1,
                           constant: 0)
第二,不要这样做:

cell?.contentView.translatesAutoresizingMaskIntoConstraints = false
第三,每次重用单元时,您的代码都会添加一个新的“橙色视图”。在自定义单元格类的init部分添加子视图要好得多,但如果要在
cellForRow
中添加子视图,请先检查它是否已经存在:

    if cell.contentView.subviews.count == 0 {
        // no, so add it here

        let view = UIView()

        // continue with view setup
第四,您可能会发现以这种方式添加约束更容易/更符合逻辑/更清晰/etc:

cell.contentView.addSubview(view)

view.topAnchor.constraint(equalTo: cell.contentView.topAnchor, constant: 0.0).isActive = true
view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor, constant: 0.0).isActive = true
view.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor, constant: 0.0).isActive = true
view.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor, constant: 0.0).isActive = true
而且。。。由于您已注册一个单元类以供重用,因此此格式将为您提供一个有效的单元:

    // instead of this
    //var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
    //if cell == nil {
    //  cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
    //}

    // better method
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

下面是完整的功能:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    // have we already added the subview?
    if cell.contentView.subviews.count == 0 {
        // no, so add it here

        let view = UIView()

        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor.orange

        cell.contentView.addSubview(view)

        view.topAnchor.constraint(equalTo: cell.contentView.topAnchor, constant: 0.0).isActive = true
        view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor, constant: 0.0).isActive = true
        view.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor, constant: 0.0).isActive = true
        view.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor, constant: 0.0).isActive = true

    }

    return cell
}

谢谢,好消息。我尝试将高度约束更改为底部约束(请参见更新的代码)。我仍然看不到任何橙色视图?您需要在
视图上设置固定高度约束。另请参见我对
tableView.rowHeight的编辑。谢谢,好消息。我尝试将高度约束更改为底部约束(请参见更新的代码)。我仍然看不到任何橙色视图?您需要在
视图上设置固定高度约束。另请参见我的编辑关于
tableView.rowHeight