调整 UITableView 的大小以适合内容
我正在创建一个应用程序,该应用程序将在 UILabel
中显示问题,并在 UITableView
中显示多项选择答案,每行显示多项选择。问题和答案会有所不同,因此我需要这个 UITableView
的高度是动态的。
我想为表格找到一个 sizeToFit
解决方法。表格框架设置为其所有内容的高度。
谁能告诉我如何实现这一目标?
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.
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.
Can anyone advise on how I can achieve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(25)
设置tableview重新加载时
只需调用下面一个即可处理内容大小
处理逻辑
self.view.layoutIfNeeded()是获取准确内容大小的关键
When setting tableview reload
Just call below one to get worked on content size
To handle logic
self.view.layoutIfNeeded() is the key to getting the exact content size
作为 Anooj VM 答案的扩展,我建议执行以下操作仅在内容大小发生变化时刷新内容大小。
这种方法还可以正确禁用滚动并支持更大的列表和旋转。不需要dispatch_async,因为contentSize更改是在主线程上调度的。
As an extension of Anooj VM's answer, I suggest the following to refresh content size only when it changes.
This approach also disable scrolling properly and support larger lists and rotation. There is no need to dispatch_async because contentSize changes are dispatched on main thread.
Musa almatri 的 objc 版本
objc version of Musa almatri
您可以尝试
使用 Storyboard 或以编程方式使用此自定义
AGTableView
设置 TableView 高度约束。 (此类自动获取高度约束并将内容视图高度设置为您的表视图高度)。注意如果设置高度有任何问题,请使用
yourTableView.layoutSubviews()
。You can try Out this Custom
AGTableView
To Set a TableView Height Constraint Using storyboard or programmatically. (This class automatically fetch a height constraint and set content view height to yourtableview height).
Note If any problem to set a Height then
yourTableView.layoutSubviews()
.我正在使用 UIView 扩展,方法接近上面的 @ChrisB 方法
实现::
奖励:可以在任何其他 UIView 上使用,例如:你自己的动态标签
I am using a UIView extension , approach is close to @ChrisB approach above
implementation : :
Bonus : Can be used on any other UIViews eg:your own dynamic label
基于fl034的答案。但对于 Xamarin.iOS 用户:
Based on answer of fl034. But for Xamarin.iOS users:
如果您希望表格是动态的,则需要使用基于表格内容的解决方案,如上所述。如果你只是想显示一个较小的表格,你可以使用容器视图并在其中嵌入一个 UITableViewController - UITableView 将根据容器大小调整大小。
这避免了大量的计算和布局调用。
If you want your table to be dynamic, you will need to use a solution based on the table contents as detailed above. If you simply want to display a smaller table, you can use a container view and embed a UITableViewController in it - the UITableView will be resized according to the container size.
This avoids a lot of calculations and calls to layout.
Swift 3 中的 Mu 解决方案:在
viewDidAppear
中调用此方法Mu solution for this in swift 3: Call this method in
viewDidAppear
无需 KVO、DispatchQueue 或自行设置约束的 Swift 5 和 4.2 解决方案。
此解决方案基于 Gulz 的回答< /a>.
创建
UITableView
的子类:将
UITableView
添加到您的布局并在所有方面设置约束。设置底部约束关系为>=(greaterThanOrEqual)。将其自定义类设置为
ContentSizedTableView
。您应该会看到一些错误,因为 Storyboard 没有考虑我们的子类的
intrinsicContentSize
。通过打开大小检查器并将 intrinsicContentSize 覆盖为占位符值来修复此问题。这是设计时间的覆盖。在运行时,它将使用ContentSizedTableView
类中的覆盖更新: 已更改 Swift 4.2 的代码。如果您使用的是早期版本,请使用
UIViewNoIntrinsicMetric
而不是UIView.noIntrinsicMetric
Swift 5 and 4.2 solution without KVO, DispatchQueue, or setting constraints yourself.
This solution is based on Gulz's answer.
Create a subclass of
UITableView
:Add a
UITableView
to your layout and set constraints on all sides. Set the bottom constraint relation to >= (greaterThanOrEqual).Set the custom class of it to
ContentSizedTableView
.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 ourContentSizedTableView
classUpdate: Changed code for Swift 4.2. If you're using a prior version, use
UIViewNoIntrinsicMetric
instead ofUIView.noIntrinsicMetric
其实我自己也找到了答案。
我只是为
tableView.frame
创建一个新的CGRect
,其height
为table.contentSize.height
设置
UITableView
的高度与其内容的height
之比。由于代码修改了 UI,因此不要忘记在主线程中运行它:
Actually I found the answer myself.
I just create a new
CGRect
for thetableView.frame
with theheight
oftable.contentSize.height
That sets the height of the
UITableView
to theheight
of its content.Since the code modifies the UI, do not forget to run it in the main thread:
Swift 解决方案
请按照以下步骤操作:
从 Storyboard 设置表格的高度约束。
从故事板中拖动高度约束并在视图控制器文件中为其创建
@IBOutlet
。然后您可以使用以下代码动态更改表格的高度:
如果最后一行被截断,请尝试在
willDisplay cell
函数中调用viewWillLayoutSubviews()
:Swift Solution
Follow these steps:
Set the height constraint for the table from the storyboard.
Drag the height constraint from the storyboard and create
@IBOutlet
for it in the view controller file.Then you can change the height for the table dynamicaly using this code:
If the last row is cut off, try to call
viewWillLayoutSubviews()
inwillDisplay cell
function:我在 iOS 7 中尝试过这个方法,它对我有用
I've tried this in iOS 7 and it worked for me
在表视图上为 contentSize 属性添加一个观察者,然后
在回调中相应地调整框架大小:
希望这会对您有所帮助。
Add an observer for the contentSize property on the table view, and adjust the frame size accordingly
then in the callback:
Hope this will help you.
我在滚动视图中有一个表视图,必须计算 tableView 的高度并相应地调整其大小。这些是我采取的步骤:
0)将 UIView 添加到您的滚动视图(可能没有此步骤也可以工作,但我这样做是为了避免任何可能的冲突)-这将是您的表视图的容器视图。如果执行此步骤,请将视图边框设置为表格视图的边框。
1) 创建 UITableView 的子类:
2) 将 Storyboard 中的表视图的类设置为 IntrinsicTableView: 截图: http://joxi. ru/a2XEENpsyBWq0A
3) 将 heightConstraint 设置为表格视图
4) 将表格的 IBoutlet 拖动到 ViewController
5) 将表格高度约束的 IBoutlet 拖动到 ViewController
6) 将此方法添加到 ViewController 中:
Hope这有帮助
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:
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.
1) create a subclass of UITableView:
2) set class of a table view in Storyboard to IntrinsicTableView: screenshot: http://joxi.ru/a2XEENpsyBWq0A
3) Set the heightConstraint to your table view
4) drag the IBoutlet of your table to your ViewController
5) drag the IBoutlet of your table's height constraint to your ViewController
6) add this method into your ViewController:
Hope this helps
Swift 5 解决方案
请遵循以下四个步骤:
设置故事板中表格视图的高度约束。
从故事板中拖动高度约束并在视图控制器文件中为其创建
@IBOutlet
。在
重写函数 viewDidLoad() 上添加 contentSize 属性的观察者
然后您可以使用以下代码动态更改表格的高度:
Swift 5 Solution
Follow these four steps:
Set the height constraint for the tableview from the storyboard.
Drag the height constraint from the storyboard and create
@IBOutlet
for it in the view controller file.Add an observer for the contentSize property on the
override func viewDidLoad()
Then you can change the height for the table dynamicaly using this code:
如果您不想自己跟踪表视图的内容大小更改,您可能会发现此子类很有用。
In case you don't want to track table view's content size changes yourself, you might find this subclass useful.
我的做法有点不同,实际上我的 TableView 在滚动视图内,所以我必须将高度约束设置为 0。
然后在运行时我做了以下更改,
I did in a bit different way, Actually my TableView was inside scrollview so i had to give height constraint as 0.
Then at runtime I made following changes,
如果您的 contentSize 不正确,这是因为它基于estimatedRowHeight(自动),请在之前使用它
来源:https://forums.developer.apple.com/thread/81895
In case your contentSize is not correct this is because it is based on the estimatedRowHeight (automatic), use this before
source : https://forums.developer.apple.com/thread/81895
Swift 3、iOS 10.3
解决方案 1:
只需将
self.tableview.sizeToFit()
放入cellForRowAt indexPath
函数中即可。确保将桌面视图高度设置得高于您的需要。如果您没有 tableview 下面的视图,这是一个很好的解决方案。但是,如果有,底部表格视图约束将不会更新(我没有尝试修复它,因为我提出了解决方案 2)
示例:
解决方案 2:
在 Storyboard 中设置 tableview 高度约束并将其拖动到 ViewController。如果您知道单元格的平均高度并且知道数组包含多少个元素,则可以执行以下操作:
*编辑:
在我尝试了所有解决方案并且每个解决方案都在修复某些问题之后,但不完全, this 是完全解释和解决此问题的答案。
Swift 3, iOS 10.3
Solution 1:
Just put
self.tableview.sizeToFit()
incellForRowAt 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)
Example:
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:
*EDIT:
After all the solutions I tried and every of them was fixing something, but not completely, this is the answer that explains and fixes this problem completely.
这对我来说很有效,使用自动布局,表格视图只有一个部分。
我在设置自动布局时调用此函数(这里的示例使用 SnapKit,但您明白了):
我希望 UITableView 仅与单元格的组合高度一样高;我循环遍历单元格并累积单元格的总高度。由于此时表视图的大小为 CGRect.zero,因此我需要设置边界以便能够遵守单元格定义的自动布局规则。我将大小设置为应该足够大的任意值。实际尺寸将由自动布局系统稍后计算。
This works for me using Auto Layout, with a table view with only one section.
I call this function when setting up Auto Layout (The sample here uses SnapKit, but you get the idea):
I want the UITableView only to be as tall as the combined height of the cells; I loop through the cells and accumulate the total height of the cells. Since the size of the table view is CGRect.zero at this point, I need to set the bounds to be able to respect the Auto Layout rules defined by the cell. I set the size to an arbitrary value that should be large enough. The actual size will be calculated later by the Auto Layout system.
如果使用自动布局,有一个更好的方法:更改确定高度的约束。只需计算表格内容的高度,然后找到约束并更改它。这是一个示例(假设确定桌子高度的约束实际上是具有关系“等于”的高度约束):
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"):
基于
fl034的答案
SWift 5
based on
fl034's answer
SWift 5
Mimo 的回答 和 Anooj VM '答案 两者都很棒,但是如果您有一个很大的列表,则有一个小问题,框架的高度可能会截断一些单元格。
所以。我对答案做了一些修改:
Mimo's answer and Anooj VM 's answer both are awesome but there is a small problem if you have a large list, it's possible that the height of the frame will cutoff some of your cells.
So. I have modified the answer a little bit:
我的 Swift 5 实现是将 tableView 的高度约束设置为其内容的大小 (
contentSize.height
)。此方法假设您使用自动布局。此代码应放置在cellForRowAt
表视图方法。My Swift 5 implementation is to set the hight constraint of the tableView to the size of its content (
contentSize.height
). This method assumes you are using auto layout. This code should be placed inside thecellForRowAt
tableView method.就我而言,我的管理方式是。
给出表格视图的任何恒定高度。创建表视图高度的出口,然后在重新加载表视图时调用以下函数。
注意:tableView是表视图的出口,tableViewHeight是tableView高度的出口。
For my case, how I manage is.
give any constant height of table view. create outlet of table view height and then call the following function where ever you relaod the tableView.
note: tableView is the outlet for your table view and tableViewHeight is the outlet for tableView height.