ios 调整 UITableView 以适应内容
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2595118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Resizing UITableView to fit content
提问by MiMo
I am creating an app which will have a question in a UILabel
and a multiple choice answers displayed in UITableView
, each row showing a multiple choice. Questions and answers will vary, so I need this UITableView
to be dynamic in height.
我正在创建一个应用程序,它将在 a 中UILabel
显示一个问题,并在 中显示一个多项选择答案UITableView
,每行显示一个多项选择。问题和答案会有所不同,所以我需要它UITableView
在高度上是动态的。
I would like to find a sizeToFit
work around for the table. Where the table's frame is set to the height of all it's content.
我想sizeToFit
为桌子找到一个解决方法。表格的框架设置为其所有内容的高度。
Can anyone advise on how I can achieve this?
任何人都可以就我如何实现这一目标提出建议吗?
采纳答案by MiMo
Actually I found the answer myself.
其实我自己找到了答案。
I just create a new CGRect
for the tableView.frame
with the height
of table.contentSize.height
我只是创建一个新CGRect
的tableView.frame
用height
的table.contentSize.height
That sets the height of the UITableView
to the height
of its content.
Since the code modifies the UI, do not forget to run it in the main thread:
这台的高度UITableView
到height
它的内容。由于代码修改了UI,所以不要忘记在主线程中运行它:
dispatch_async(dispatch_get_main_queue(), ^{
//This code will run in the main thread:
CGRect frame = self.tableView.frame;
frame.size.height = self.tableView.contentSize.height;
self.tableView.frame = frame;
});
回答by fl034
Swift 5 and 4.2 solution without KVO, DispatchQueue, or setting constraints yourself.
没有 KVO、DispatchQueue 或自己设置约束的 Swift 5 和 4.2 解决方案。
This solution is based on Gulz's answer.
此解决方案基于Gulz 的回答。
1) Create a subclass of UITableView
:
1)创建一个子类UITableView
:
import UIKit
final class ContentSizedTableView: UITableView {
override var contentSize:CGSize {
didSet {
invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
layoutIfNeeded()
return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
}
}
2) Add a UITableView
to your layout and set constraints on all sides. Set the class of it to ContentSizedTableView
.
2) 将 a 添加UITableView
到您的布局并在所有方面设置约束。将它的类设置为ContentSizedTableView
.
3) You should see some errors, because Storyboard doesn't take our subclass' intrinsicContentSize
into account. Fix this by opening the size inspector and overriding the intrinsicContentSize to a placeholder value. This is an override for design time. At runtime it will use the override in our ContentSizedTableView
class
3) 您应该会看到一些错误,因为 Storyboard 没有考虑我们的子类intrinsicContentSize
。通过打开大小检查器并将 internalContentSize 覆盖为占位符值来解决此问题。这是设计时的覆盖。在运行时它将使用我们ContentSizedTableView
类中的覆盖
Update:Changed code for Swift 4.2. If you're using a prior version, use UIViewNoIntrinsicMetric
instead of UIView.noIntrinsicMetric
更新:更改了 Swift 4.2 的代码。如果您使用的是以前的版本,请使用UIViewNoIntrinsicMetric
代替UIView.noIntrinsicMetric
回答by Musa almatri
Swift Solution
快速解决方案
Follow these steps:
按着这些次序:
1- Set the height constraint for the table from the storyboard.
1- 从情节提要中设置表格的高度约束。
2- Drag the height constraint from the storyboard and create @IBOutlet for it in the view controller file.
2- 从情节提要中拖动高度约束并在视图控制器文件中为其创建@IBOutlet。
@IBOutlet weak var tableHeight: NSLayoutConstraint!
3- Then you can change the height for the table dynamicaly using this code:
3-然后您可以使用以下代码动态更改表格的高度:
override func viewWillLayoutSubviews() {
super.updateViewConstraints()
self.tableHeight?.constant = self.table.contentSize.height
}
Update
更新
If the last row is cut for you, try to call viewWillLayoutSubviews() in willDisplay cell function:
如果最后一行被剪掉了,尝试在 willDisplay 单元格函数中调用 viewWillLayoutSubviews() :
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
self.viewWillLayoutSubviews()
}
回答by Alexey
I've tried this in iOS 7 and it worked for me
我在 iOS 7 中试过这个,它对我有用
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView sizeToFit];
}
回答by Anooj VM
Add an observer for the contentSize property on the table view, and adjust the frame size accordingly
为 table view 上的 contentSize 属性添加一个观察者,并相应地调整框架大小
[your_tableview addObserver:self forKeyPath:@"contentSize" options:0 context:NULL];
then in the callback:
然后在回调中:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
CGRect frame = your_tableview.frame;
frame.size = your_tableview.contentSize;
your_tableview.frame = frame;
}
Hope this will help you.
希望这会帮助你。
回答by Gulz
I had a table view inside scroll view and had to calculate tableView's height and resize it accordingly. Those are steps I've taken:
我在滚动视图中有一个表格视图,必须计算 tableView 的高度并相应地调整它的大小。这些是我采取的步骤:
0) add a UIView to your scrollView (probably will work without this step but i did it to avoid any possible conflicts) - this will be a containr view for your table view. If you take this step , then set the views borders right to tableview's ones.
0)将 UIView 添加到您的滚动视图(可能无需此步骤即可工作,但我这样做是为了避免任何可能的冲突) - 这将是您的表视图的容器视图。如果您执行此步骤,则将视图边框设置为 tableview 的边框。
1) create a subclass of UITableView:
1)创建一个UITableView的子类:
class IntrinsicTableView: UITableView {
override var contentSize:CGSize {
didSet {
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
self.layoutIfNeeded()
return CGSize(width: UIViewNoIntrinsicMetric, height: contentSize.height)
}
}
2) set class of a table view in Storyboard to IntrinsicTableView: screenshot: http://joxi.ru/a2XEENpsyBWq0A
2)将 Storyboard 中表格视图的类设置为 IntrinsicTableView:截图:http: //joxi.ru/a2XEENpsyBWq0A
3) Set the heightConstraint to your table view
3) 将 heightConstraint 设置为您的表格视图
4) drag the IBoutlet of your table to your ViewController
4) 将表的 IBoutlet 拖到 ViewController
5) drag the IBoutlet of your table's height constraint to your ViewController
5) 将你的表格高度约束的 IBoutlet 拖到你的 ViewController
6) add this method into your ViewController:
6) 将此方法添加到您的 ViewController 中:
override func viewWillLayoutSubviews() {
super.updateViewConstraints()
self.yourTableViewsHeightConstraint?.constant = self.yourTableView.intrinsicContentSize.height
}
Hope this helps
希望这可以帮助
回答by xinatanil
In case you don't want to track table view's content size changes yourself, you might find this subclass useful.
如果您不想自己跟踪 table view 的内容大小更改,您可能会发现这个子类很有用。
protocol ContentFittingTableViewDelegate: UITableViewDelegate {
func tableViewDidUpdateContentSize(_ tableView: UITableView)
}
class ContentFittingTableView: UITableView {
override var contentSize: CGSize {
didSet {
if !constraints.isEmpty {
invalidateIntrinsicContentSize()
} else {
sizeToFit()
}
if contentSize != oldValue {
if let delegate = delegate as? ContentFittingTableViewDelegate {
delegate.tableViewDidUpdateContentSize(self)
}
}
}
}
override var intrinsicContentSize: CGSize {
return contentSize
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
return contentSize
}
}
回答by Yohan Dahmani
In case your contentSize is not correct this is because it is based on the estimatedRowHeight (automatic), use this before
如果您的 contentSize 不正确,这是因为它基于估计的行高度(自动),请在此之前使用
tableView.estimatedRowHeight = 0;
tableView.estimatedRowHeight = 0;
回答by ?or?e Nilovi?
Swift 3, iOS 10.3
斯威夫特 3,iOS 10.3
Solution 1:Just put self.tableview.sizeToFit()
in cellForRowAt indexPath
function. Make sure to set tableview height higher then you need.
This is a good solution if you don't have views below tableview. However, if you have, bottom tableview constraint will not be updated (I didn't try to fix it because I came up with solution 2)
解决方法1:只要把self.tableview.sizeToFit()
在cellForRowAt indexPath
函数。确保将 tableview 高度设置为高于您需要的高度。如果您在 tableview 下没有视图,这是一个很好的解决方案。但是,如果有,则底部 tableview 约束将不会更新(我没有尝试修复它,因为我想出了解决方案 2)
Example:
例子:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell", for: indexPath) as? TestCell {
cell.configureCell(data: testArray[indexPath.row])
self.postsTableView.sizeToFit()
return cell
}
return UITableViewCell()
}
Solution 2:Set tableview height constraint in storyboard and drag it to the ViewController. If you know the average height of your cell and you know how many elements your array contains, you can do something like this:
解决方案2:在storyboard中设置tableview的高度约束并将其拖到ViewController中。如果您知道单元格的平均高度并且知道数组包含多少个元素,则可以执行以下操作:
tableViewHeightConstraint.constant = CGFloat(testArray.count) * 90.0 // Let's say 90 is the average cell height
*EDIT:
*编辑:
After all the solutions I tried and every of them was fixing something, but not completely, thisis the answer that explains and fixes this problem completely.
在我尝试了所有解决方案之后,每个解决方案都在修复某些问题,但不是完全解决,这是完全解释和解决此问题的答案。
回答by ChrisB
There is a much better way to do it if you use AutoLayout: change the constraint that determines the height. Just calculate the height of your table contents, then find the constraint and change it. Here's an example (assuming that the constraint that determines your table's height is actually a height constraint with relation "Equal"):
如果您使用 AutoLayout,有一个更好的方法来做到这一点:更改确定高度的约束。只要计算你的表内容的高度,然后找到约束和改变它。这是一个示例(假设确定表格高度的约束实际上是具有关系“Equal”的高度约束):
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
for constraint in tableView.constraints {
if constraint.firstItem as? UITableView == tableView {
if constraint.firstAttribute == .height {
constraint.constant = tableView.contentSize.height
}
}
}
}