Swift TableViewCell xib没有约束

时间:2017-04-20 13:30:51

标签: ios xcode uitableview uistoryboard xib

我有两个TableView,当我设计原始版本时,我使用故事板中的原型单元设计它,使其可重复使用我试图将其拉出.xib并加载它。当它从cellID.xib加载时,它会在运行时丢失所有约束,并且所有约束都是相互叠加的。

TableViewController

let cellIdentifier = "cellID"
override func viewDidLoad() {
    super.viewDidLoad()

    tableView.register(UINib(nibName: cellIdentifier, bundle: nil), forCellReuseIdentifier: cellIdentifier)
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 300
}

故事板中的原型单元格(用于工作)

prototype cell

复制粘贴到XIB时的单元格

xib cell

约束

contraints on cell

XIB视图层次结构

xib view hierarchy

4 个答案:

答案 0 :(得分:4)

问题

在您的问题标题中,您询问了如何解决Swift TableViewCell xib没有约束的问题。"此外,在赏金中,您指定答案应为:

  

一个足够的答案,显示为什么移动到a时约束会丢失   xib,当它们存在于xib中时,以及如何解决这个问题。

据我了解,您的问题分为两部分:

  1. 自定义TableViewCell xib没有约束的问题
  2. 为什么从Storyboard原型复制/粘贴到xib
  3. 时会丢失约束

    对于问题#1,我使用了与您在自定义单元格xib中的屏幕截图中显示的几乎所有相同的约束,并且它有效。我将在下面详细解释。

    对于问题#2,我发现约束不会丢失。您可能需要共享您的项目,以便其他人可以复制您遇到的问题。我将具有类似约束的Storyboard原型单元复制/粘贴到xib上,并且我没有任何约束问题。所以我可以确认复制/粘贴功能是否有效。

    解决方案演示

    我创建了以下演示来测试您的问题。请参阅下面的屏幕截图。 tableView包含六个单元格。第一个和第二个相同,并且具有重用标识符MyCell。第3个和第4个相同,并且具有重用标识符MyCopyPasteCell。第5和第6个是相同的并且具有重用标识符MyPrototypeCell

    MyCell存在于xib中,并且几乎使用了屏幕截图中显示的所有相同约束。如您所见,没有约束问题。 MyCopyPasteCell使用类似的约束,并从Storyboard原型复制/粘贴到xib。 MyPrototypeCell是复制的原始原型。即使将原型复制到xib,最后四个单元看起来完全相同。从原型到xib的约束没有问题。

    enter image description here

    约束

    在下面的代码中,我列出了您在 ContentView 的屏幕截图中显示的所有约束。 (请注意,我还实现了height=20aspect=1:1height=75约束,但它们未在下面列出。)由于我没有使用它们,因此注释掉了两个约束。我还添加了一个约束来替换另一个未使用的约束。

    // bottomMargin = Profile Image View.bottom + 188.5
    bottomMargin = Profile Image.bottom + 17
    Profile Image View.top = Username Label.top
    Profile Image View.leading = leadingMargin + 2
    Profile Image View.top = topMargin + 20
    Username Label.leading = Content Text View.leading    
    // Username Label.top = topMargin + 20        
    Username Label.trailing = Content Text View.trailing
    Username Label.leading = Profile Image View.trailing + 15
    trailingMargin = Username Label.trailing + 10
    Content Text View.top = Username Label.bottom + 5
    Content Text View.leading = leadingMargin + 92
    bottomMargin = Content Text View.bottom + 20
    

    第一个评论约束// bottomMargin = Profile Image View.bottom + 188.5没有意义,因为它会将图像的底部与单元格的底部分开188.5。这也完全不符合故事板(用于工作)屏幕截图中的原型单元格。我将其替换为bottomMargin = Profile Image.bottom + 17,它只用188替换188.5。

    第二个注释约束// Username Label.top = topMargin + 20(将username和topMargin分隔为20)在技术上可以正常工作。但是,它的功能对于Profile Image.top = topMargin + 20(将Profile Image和topMargin分隔为20)和Profile Image View.top = Username Label.top(将配置文件图像和用户名设置为相同的顶部分隔,即20)而言是多余的。

    MyTableViewController

    以下是我的视图控制器。基本上我创建了三个部分,每个部分有两个单元格/行。 MyCellMyCopyPasteTableViewCell来自xib并在viewDidLoad()中注册。 MyPrototypeCell来自故事板,未在viewDidLoad()注册。

    //  MyTableViewController.swift
    import UIKit    
    class MyTableViewController: UITableViewController {
    
        let myCell = "MyCell"
        let myCopyPasteCell = "MyCopyPasteTableViewCell"
        let myPrototypeCell = "MyPrototypeCell"
    
        override func viewDidLoad() {
            super.viewDidLoad()
            tableView.register(UINib(nibName: myCell, bundle: nil), forCellReuseIdentifier: myCell)
            tableView.register(UINib(nibName: myCopyPasteCell, bundle: nil), forCellReuseIdentifier: myCopyPasteCell)
            tableView.rowHeight = UITableViewAutomaticDimension
            tableView.estimatedRowHeight = 300
        }
    
        // MARK: - Table view data source
        override func numberOfSections(in tableView: UITableView) -> Int {
            return 3
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 2
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            if indexPath.section == 0 {
                let cell = tableView.dequeueReusableCell(withIdentifier: myCell, for: indexPath)
                return cell
            } else if indexPath.section == 1 {
                let cell = tableView.dequeueReusableCell(withIdentifier: myCopyPasteCell, for: indexPath)
                return cell
            } else {
                let cell = tableView.dequeueReusableCell(withIdentifier: myPrototypeCell, for: indexPath)
                return cell
            }
        }
    }
    

    Github链接

    https://github.com/starkindustries/TableViewCellConstraintsTest

答案 1 :(得分:2)

问题和解决方案

您可能已禁用XIB的Autolayout将其ON从右上方菜单转到File Inspector

enter image description here

您可以按照从Xib创建单元格的简单步骤

1。使用UITableCell创建.xib(✅也创建Xib文件) enter image description here

2. :提供单元格标识符

enter image description here

3。布局约束

ImageView提供TopLeftBottom的对象        高度常数和宽高比[我已设置边框以显示框架]

UIlable title lable从三个方面给出约束        来自TopLeftRight NumberOflines=0(不要让身高不变 -   ⚠️如果发出警告继续并更新约束条件

UIlable Descriptions lable给出了所有四方的约束NumberOflines=0         (⚠️这会给你一个错误去建议并改变UIlable约束的优先级

请参阅下面的屏幕截图enter image description here

更改优先级 enter image description here  而不是再次更新约束

4. UIViewController

中的代码
 @IBOutlet var tableView: UITableView!

    var cellIdentifier="cell"
    var cellXibName = "MyTableCell"


    override func viewDidLoad() {
        super.viewDidLoad()


        tableView.register(UINib(nibName: cellXibName, bundle: nil), forCellReuseIdentifier: cellIdentifier)
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 320


    }



    func numberOfSections(in tableView1: UITableView) -> Int {
        return 3
    }

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

            let cell :MyTableCell = tableView1.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! MyTableCell


            return cell
    }

最后输出完美如你所愿

<强>输出 enter image description here

我希望这对你有用......如果这对你有用,请告诉我。

答案 2 :(得分:0)

解决方案:

我解决了你的问题。希望对你有所帮助

我使用uiview剪辑所有单元格元素。enter image description here

和细胞设计 enter image description here

代码:

类ViewController:UIViewController {

stderr

结果: enter image description here

答案 3 :(得分:-1)

似乎细胞高度是问题,对吧?因此,约束无法正常工作。

使用XIB files时需要此覆盖功能:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return 300
}

然而,你的约束必定是错误的,或者让我们说它们并不完美。我知道他们正在使用故事板中的原型单元,但这并不能使它们100%完美正常工作吗? 您的UIImageView没有heightwidth。您应该尝试使用一些约束来设置它。 (或者设置width并使用Aspect Ratio约束)