【问题标题】:Add and layout subviews loaded from xib to a custom cell添加和布局从 xib 加载的子视图到自定义单元格
【发布时间】:2016-06-27 13:26:45
【问题描述】:

我有一个自定义单元格“CustomCell”,我希望根据自定义数据元素进行组合。 我正在尝试将子视图添加到 CustomCell 但对于从 xib (https://stackoverflow.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 加载的

标签: ios swift uitableview xib nslayoutconstraint


【解决方案1】:

需要注意的几件事

  1. 在 layoutSubviews 中,您不应该添加/删除不变的约束。如果您设置了约束,默认实现 (super.layoutSubviews()) 将根据约束调整大小/布局。

  2. 如果您设置了约束,它们会覆盖任何已设置的框架。

  3. 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也没有解决问题
猜你喜欢
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-07
  • 2016-10-17
相关资源
最近更新 更多