【问题标题】:Add a view from a xib file to a UITableViewCell adding constraints将 xib 文件中的视图添加到 UITableViewCell 添加约束
【发布时间】:2015-12-20 09:44:57
【问题描述】:

我创建了一个带有自定义视图的 xib 文件,我想在 UITableViewCell 中显示该文件。

问题是:在 xib 文件中,我将 UIView 的宽度设置为 600(sizeFreeform)但我想使用约束来获得每个设备的正确宽度。

我在UITableViewCelladdSubview() 中添加了这个视图,所以我认为这个视图必须约束到单元格的视图,对吗?我该怎么做?

我添加了一些代码:

这是我自定义的UIView 与 xib 文件相关:

class DownloadView: UIView, NSURLSessionDownloadDelegate{

///utilizzata per mostrare il nome del file in download
@IBOutlet var nomeFileInDownloadLabel: UILabel!

///utilizzata per mostrare la percentuale di download completato
@IBOutlet var quantitaScaricataLabel: UILabel!

///utilizzata per mostrare il download
@IBOutlet var progressView: UIProgressView!

var view : UIView!

private var downloadTask: NSURLSessionDownloadTask?

//Initialization
override init(frame: CGRect) {
    super.init(frame: frame)
    xibSetup()
}

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
}


//I setup the xib from here
func xibSetup() {
    view = loadViewFromNib()

    //if I set the following one the view is a square
    //view.frame = bounds

    // Make the view stretch with containing view
    view.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
    self.addSubview(view)
}

//I load the xib file
func loadViewFromNib() -> UIView {

    let bundle = NSBundle(forClass: self.dynamicType)
    let nib = UINib(nibName: "View", bundle: bundle)
    let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
    return view
}
//some code for other task 
...
}

在我的UITableView 方法tableView(tableView:cellForRowAtIndexPath) 中添加视图:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("DownloadRootTVC_IDcell", forIndexPath: indexPath) as! DownloadTVCell

    //I get my custom view from an array
    let myView = self.listOfViewsDownlaod[indexPath.row]

    //I add the view to the cell
    cell.addSubview(myView)


    return cell
}

在最后一种方法中,我认为我必须设置约束以适应 UITableViewCell 中的自定义视图,使其适应设备宽度。

编辑:

由于我想使子视图的宽度和高度适应单元格,所以我写了这个:

    let topConstraint = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: cell, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 8)
    cell.addConstraint(topConstraint)

    let bottomConstraint = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: cell, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 8)
    cell.addConstraint(bottomConstraint)

    let leftConstraint = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: cell, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 20)
    cell.addConstraint(leftConstraint)

    let rightConstraint = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.TrailingMargin, relatedBy: NSLayoutRelation.Equal, toItem: cell, attribute: NSLayoutAttribute.TrailingMargin, multiplier: 1, constant: 20)
    cell.addConstraint(rightConstraint)

唯一不起作用的是正确的,视图继续在屏幕上。我也尝试使用NSLayoutAttribute.RightNSLayoutAttribute.RighMargin 或将常量设置为负值,但不起作用。

【问题讨论】:

    标签: swift uitableview constraints xib


    【解决方案1】:

    当您将其添加为子视图时,您的 xib 视图对其父视图没有任何限制。您应该以编程方式创建它们。 There is 一个很好的例子。例如,如果你想把你的视图放在超级视图的中心并且大小相同,你可以写下一个:

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
      let cell = tableView.dequeueReusableCellWithIdentifier("cell")!
      let myView = UIView()
      myView.backgroundColor = UIColor.redColor()
      myView.translatesAutoresizingMaskIntoConstraints = false
      cell.addSubview(myView)
      let horizontalConstraint = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: cell, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)
      cell.addConstraint(horizontalConstraint)
    
      let verticalConstraint = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: cell, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0)
      cell.addConstraint(verticalConstraint)
    
      let widthConstraint = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: cell, attribute: NSLayoutAttribute.Width, multiplier: 1, constant: 0)
      cell.addConstraint(widthConstraint)
    
      let heightConstraint = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: cell, attribute: NSLayoutAttribute.Height, multiplier: 1, constant: 0)
      cell.addConstraint(heightConstraint)
      return cell
    }
    

    它看起来像这样(蓝色 - tableView,红色 - myView):

    【讨论】:

    • 感谢您的帮助。不幸的是,由于这些限制导致应用程序崩溃,我将学习如何使用它们以便正确使用它们。谢谢
    • @Ernesto,好的,也许您可​​以显示您的错误,我会尽力提供帮助?
    • 我收到这个错误:Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSLayoutConstraint constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:]: Unknown layout attribute' 你怎么看?非常感谢!!
    • @Ernesto,是的,对不起。我的错。宽度和高度约束的 NSLayoutAttribute 不应该是 .NotAnAttribute。我更新了我的答案。
    • 好的,谢谢!今天晚上我会试试新代码。我会告诉你的
    【解决方案2】:

    终于找到问题了:

    问题出在xibSetup() 方法中,因为我加载了xib 但我没有设置约束!所以我的新方法是:

    func xibSetup() {
        let myView = loadViewFromNib()
    
        myView.translatesAutoresizingMaskIntoConstraints = false
    
        self.addSubview(myView)
    
        let leading = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: myView.superview, attribute: NSLayoutAttribute.Leading, multiplier: 1, constant: 0)
        self.addConstraint(leading)
    
        let bottom = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: myView.superview, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 0)
        self.addConstraint(bottom)
    
        let trailing = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: myView.superview, attribute: NSLayoutAttribute.Trailing, multiplier: 1, constant: 0)
        self.addConstraint(trailing)
    
        let top = NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: myView.superview, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 0)
        self.addConstraint(top)
    
    }
    

    这解决了我的问题。

    【讨论】:

      猜你喜欢
      • 2014-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-25
      • 2020-04-01
      • 2016-08-30
      • 1970-01-01
      相关资源
      最近更新 更多