添加和布局从 xib 加载的子视图到自定义单元格
Posted
技术标签:
【中文标题】添加和布局从 xib 加载的子视图到自定义单元格【英文标题】:Add and layout subviews loaded from xib to a custom cell 【发布时间】:2016-06-27 13:26:45 【问题描述】:我有一个自定义单元格“CustomCell”,我希望根据自定义数据元素进行组合。 我正在尝试将子视图添加到 CustomCell 但对于从 xib (https://***.com/a/26326006/3546621) 加载的子视图,我无法弄清楚如何将它们布局到单元格的 contentView 中;即以编程方式设置框架或添加约束似乎有效。 (CustomCell 没有附加 xib,每个子视图都是以编程方式加载的。其中一些子视图是从 xib 加载的。)
例如,这是我的自定义单元格。它有两个子视图,一个用 UIView(frame: CGRect()) 初始化的黄色视图和一个用 UIView.fromNib 初始化的蓝色视图的正下方。
这是 BlueView.xib
我没有成功将 blueView 放在 yellowView 下面,而是将 blueView 堆叠在 yellowView 之上:
class CustomCell: UITableViewCell
let yellowView: UIView = UIView()
let blueViewFromXib: BlueView = UIView.fromNib()
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
fun configureForData(custom: Custom)
yellowView.backgroundColor = UIColor.yellowColor()
yellowView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(yellowView)
blueView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(blueView)
layoutIfNeeded()
override func layoutSubviews()
super.layoutSubviews()
let height = NSLayoutConstraint(item: contentView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 80)
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.addConstraint(height)
yellowView.frame = CGRect(x: 0, y: 0, width: contentView.frame.width, height: 40)
// I want to add the blueView at the bottom of the yellowView
// Option 1: not working
blueView.frame = CGRect(x: 0, y: 40, width: contentView.frame.width, height: 40)
// Option 2: not working
let top = NSLayoutConstraint(item: blueView, attribute: .Top, relatedBy: .Equal, toItem: contentView, attribute: .Top, multiplier: 1, constant: 40)
let bottom = NSLayoutConstraint(item: blueView, attribute: .Bottom, relatedBy: .Equal, toItem: contentView, attribute: .Bottom, multiplier: 1, constant: 0)
let leading = NSLayoutConstraint(item: blueView, attribute: .Leading, relatedBy: .Equal, toItem: contentView, attribute: .Leading, multiplier: 1, constant: 0)
let trailing = NSLayoutConstraint(item: blueView, attribute: .Trailing, relatedBy: .Equal, toItem: contentView, attribute: .Trailing, multiplier: 1, constant: 0)
contentView.addConstraints([top, bottom, leading, trailing])
class BlueView: UIView
// the project includes a BlueView.xib which is simply a UIView whose background color is blue
视图控制器
override func viewDidLoad()
super.viewDidLoad()
tableView.delegate = self
tableView.datasource = self
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 80
tableView.registerClass(CustomCell.self, forCellReuseIdentifier: "CustomCell")
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let custom = customs[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("CustomCell") as! CustomCell
cell.configureForData(custom)
return cell
【问题讨论】:
如果您使用笔尖,您可以在那里布局视图。您是否有理由要手动执行此操作? @PEEJWEEJ 我知道如何自己布局子视图(即 nib 加载子视图的子视图)。但我没有成功将子视图布置到单元格的内容视图中。 您可以将视图添加到 nib 中的单元格并与 IBOutlets 连接 顺便说一句,您在 layoutSubviews 中设置框架的代码正在将它们设置为新的 UIView...甚至不应该编译 @PEEJWEEJ 请检查代码。自定义单元格没有 xib。我想以编程方式构建它。只有一些构成最终单元格的子视图是从 xib 加载的 【参考方案1】:需要注意的几件事
在 layoutSubviews 中,您不应该添加/删除不变的约束。如果您设置了约束,默认实现 (super.layoutSubviews()
) 将根据约束调整大小/布局。
如果您设置了约束,它们会覆盖任何已设置的框架。
blueView.frame = UIView(frame: CGRect(x: 0, y: 40, width: contentView.frame.width, height: 40))
甚至不应该编译。您正在将 blueView 的框架(CGRect)设置为 UIView 的新实例。
无论如何,您似乎正在为 blueView 使用 layoutConstraints,并为 YellowView 手动设置框架。我猜如果您使用其中之一,您将能够弄清楚发生了什么。
为简化操作,请尝试将您的子视图设置为可选项:
let yellowView: UIView?
let blueViewFromXib: BlueView?
然后注释掉layoutSubviews,使用这个:
func configureForData(custom: Custom)
if yellowView == nil
yellowView = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: 40))
yellowView?.backgroundColor = UIColor.yellowColor()
self.addSubview(yellowView)
if blueView == nil
blueView = BlueView.fromNib()
blueView?.frame = CGRect(x: 0, y: 40, width: self.frame.width, height: 40)
self.addSubview(blueView)
【讨论】:
3.是一个错字。刚改正。我一直在尝试只对黄色和蓝色视图使用约束,或者只对黄色和蓝色视图使用框架。没有成功。 添加了一个我认为应该可以工作的例子,但没有完全测试它。 它甚至没有编译,但是即使修复它,这个sn-p也没有解决问题以上是关于添加和布局从 xib 加载的子视图到自定义单元格的主要内容,如果未能解决你的问题,请参考以下文章
来自 XIB 的自定义 UIView 加载具有巨大规模的子视图
如何将 xib 的子视图显示到另一个 xib 的表格单元加载中