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