我有两个TableView
,当我设计原始版本时,我使用故事板中的原型单元设计它,使其可重复使用我试图将其拉出.xib
并加载它。当它从cellID.xib
加载时,它会在运行时丢失所有约束,并且所有约束都是相互叠加的。
let cellIdentifier = "cellID"
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: cellIdentifier, bundle: nil), forCellReuseIdentifier: cellIdentifier)
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 300
}
答案 0 :(得分:4)
在您的问题标题中,您询问了如何解决Swift TableViewCell xib没有约束的问题。"此外,在赏金中,您指定答案应为:
一个足够的答案,显示为什么移动到a时约束会丢失 xib,当它们存在于xib中时,以及如何解决这个问题。
据我了解,您的问题分为两部分:
对于问题#1,我使用了与您在自定义单元格xib中的屏幕截图中显示的几乎所有相同的约束,并且它有效。我将在下面详细解释。
对于问题#2,我发现约束不会丢失。您可能需要共享您的项目,以便其他人可以复制您遇到的问题。我将具有类似约束的Storyboard原型单元复制/粘贴到xib上,并且我没有任何约束问题。所以我可以确认复制/粘贴功能是否有效。
我创建了以下演示来测试您的问题。请参阅下面的屏幕截图。 tableView包含六个单元格。第一个和第二个相同,并且具有重用标识符MyCell
。第3个和第4个相同,并且具有重用标识符MyCopyPasteCell
。第5和第6个是相同的并且具有重用标识符MyPrototypeCell
。
MyCell
存在于xib中,并且几乎使用了屏幕截图中显示的所有相同约束。如您所见,没有约束问题。 MyCopyPasteCell
使用类似的约束,并从Storyboard原型复制/粘贴到xib。 MyPrototypeCell
是复制的原始原型。即使将原型复制到xib,最后四个单元看起来完全相同。从原型到xib的约束没有问题。
在下面的代码中,我列出了您在 ContentView 的屏幕截图中显示的所有约束。 (请注意,我还实现了height=20
,aspect=1:1
和height=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)而言是多余的。
以下是我的视图控制器。基本上我创建了三个部分,每个部分有两个单元格/行。 MyCell
和MyCopyPasteTableViewCell
来自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
}
}
}
https://github.com/starkindustries/TableViewCellConstraintsTest
答案 1 :(得分:2)
问题和解决方案
您可能已禁用XIB的Autolayout
将其ON
从右上方菜单转到File Inspector
您可以按照从Xib创建单元格的简单步骤
1。使用UITableCell
创建.xib
(✅也创建Xib文件)
2. :提供单元格标识符
3。布局约束
ImageView
提供Top
,Left
和Bottom
的对象
高度常数和宽高比[我已设置边框以显示框架]
UIlable
title lable
从三个方面给出约束
来自Top
,Left
和Right
NumberOflines=0
(不要让身高不变 -
⚠️如果发出警告继续并更新约束条件
UIlable
Descriptions lable
给出了所有四方的约束NumberOflines=0
(⚠️这会给你一个错误去建议并改变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
}
最后输出完美如你所愿
我希望这对你有用......如果这对你有用,请告诉我。
答案 2 :(得分:0)
答案 3 :(得分:-1)
似乎细胞高度是问题,对吧?因此,约束无法正常工作。
使用XIB files
时需要此覆盖功能:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 300
}
然而,你的约束必定是错误的,或者让我们说它们并不完美。我知道他们正在使用故事板中的原型单元,但这并不能使它们100%完美正常工作吗?
您的UIImageView
没有height
和width
。您应该尝试使用一些约束来设置它。 (或者设置width
并使用Aspect Ratio
约束)