Swift TableViewCell xib没有约束
我有两个TableView
,当我devise原始的时候,我使用故事板中的原型单元格来devise它,为了使它可重用,我尝试将它拉出到一个.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 }
Storyboard中的原型单元格(用于工作)
复制粘贴到XIB时的单元格
约束
XIB视图层次结构
问题
在你的问题标题中,你问了如何解决“Swift TableViewCell xib没有约束”的问题。 另外在赏金中,你指定答案应该是:
一个适当的答案,说明为什么在移动到xib时,xib存在时约束会丢失,以及如何解决这个问题。
根据我的理解,你的问题有两个部分:
- 问题自定义TableViewCell xib没有约束
- 为什么在从Storyboard原型复制/粘贴到xib时,约束会丢失
对于问题#1,我使用了几乎所有的相同的约束,你已经显示在自定义单元格xib中的屏幕截图,它的工作。 我将在下面更详细地解释。
对于问题#2,我发现约束不会丢失。 您可能需要分享您的项目,以便其他人可以复制您遇到的问题。 我复制/粘贴了一个类似约束的故事板原型单元到一个xib,我没有任何约束的问题。 所以我可以确认复制/粘贴function是否有效。
解决scheme演示
我创build了以下演示来testing您的问题。 请参阅下面的截图。 tableView包含六个单元格。 第一和第二是相同的,有重用标识符MyCell
。 第三和第四是相同的,并有重用标识符MyCopyPasteCell
。 第五和第六是相同的,并有重用标识MyPrototypeCell
。
MyCell
存在于xib中,几乎使用了您在屏幕截图中显示的所有相同约束。 正如你所看到的,没有约束问题。 MyCopyPasteCell
使用类似的约束,从Storyboard原型复制/粘贴到xib。 MyPrototypeCell
是被复制的原始原型。 即使原型被复制到xib,最后四个单元看起来完全一样。 从原型到xib的约束没有问题。
约束
在下面的代码中,我列出了在您的屏幕截图中为您的ContentView显示的所有约束。 (注意,我也实现了height=20
, aspect=1:1
和height=75
约束,尽pipe它们没有在下面列出)。由于我没有使用它们,所以有两个约束被注释掉了。 我还添加了一个约束来replace另一个未使用的约束。
// 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
replace它, bottomMargin = Profile Image.bottom + 17
用17replace了188.5。
第二个注释的约束// Username Label.top = topMargin + 20
(它将用户名和topMargin分隔20)可以在技术上工作。 然而,它的function是多余的Profile Image.top = topMargin + 20
(它分隔configuration文件图像和topMargin 20)和Profile Image View.top = Username Label.top
(设置configuration文件图像和用户名相同的顶部分离即由20)。
MyTableViewController
以下是我的视图控制器。 基本上我创build了三节,每节有两个单元/行。 MyCell
和MyCopyPasteTableViewCell
来自xib,并在viewDidLoad()
中注册。 MyPrototypeCell
来自Storyboard,未在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
问题和解决scheme
您可能已经禁用了您的XIB的Autolayout
将其ON
,从右上angular的菜单转到File Inspector
你可以按照简单的步骤从Xib创build单元格
1.用.xib创buildUITableCell
(✅也创buildXib文件)
2.给出小区标识符
3.布局约束
🔸ImageView提供从Left
和下angular高度常数和长宽比[我已设置边框显示框架]
🔸 title lable
UIlable
来自Top
, Left
和Right
三个方面的限制。NumberOflines NumberOflines=0
(🚫不要给高度常量 – 如果给出警告继续并更新约束,
🔸对于Descriptions lable
扩展UIlable
来自所有四方的约束也NumberOflines=0
(⚠️这会给你一个错误去build议,并改变UIlable
约束的优先级)
看下面的截图
改变优先 比再次更新限制
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 }
最后,输出是完美的,你想要的
OUTPUT
我希望这会对你有用……请让我知道这是否适用于你。
解答:
我是你的问题的存档解决scheme。 希望这可能对你有所帮助
我使用uiview来剪辑所有单元格元素。
和细胞devise
代码:
class ViewController:UIViewController {
@IBOutlet var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() self.tableView.estimatedRowHeight = 100 self.tableView.rowHeight = UITableViewAutomaticDimension self.tableView.register(UINib(nibName: "TestCell", bundle: Bundle.main), forCellReuseIdentifier: "TestCell") // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } extension ViewController : UITableViewDataSource, UITableViewDelegate { func numberOfSections(in tableView: UITableView) -> Int { return 1; } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 10 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell", for: indexPath) as! TestCell cell.selectionStyle = .none return cell } }
结果:
细胞高度似乎是问题,对吗? 因为这个约束不能正确地工作。
在使用XIB files
时,您需要使用此重写function:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 300 }
然而,你的约束必须是错的,或者让我们说他们并不完美。 我知道他们正在使用故事板中的原型单元格,但是这并不能使他们100%完美的工作正确吗? 你的UIImageView
没有height
和width
。 你应该尝试设置一些约束。 (或者设置width
并使用Aspect Ratio
约束)