UITableView 的 tableHeaderView height 属性在加载和旋转期间更改为奇怪的值
我有一个自定义 UIView,在 loadView 期间将其设置为 UITableView 的 tableHeaderView 属性:
headerView = [[MYViewClass alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 120)];
[headerView sizeToFit];
self.tableView.tableHeaderView = headerView;
视图绘制不正确,部分视图被剪切,表格上方有空白。旋转设备时,视图几乎消失。向后旋转时,视图现在大于标题的空间,并遮挡了表格中的一些单元格。
为了排除故障,我在自定义视图类中覆盖了 setFrame 方法:
- (void) setFrame:(CGRect)frame {
[super setFrame:frame];
NSLog(@"%@ - %@", NSStringFromSelector(_cmd), NSStringFromCGRect(frame));
}
我还在 NSLog 语句上放置了一个断点,这样我就可以看到所谓的 setFrame 的内容,并且得到了一些我无法解释的奇怪结果,希望有人能够摆脱一些阐明正在发生的事情及其原因。
在loadView期间
1. initWithFrame calls: setFrame: - {{0, 0}, {320, 120}}
2. sizeToFit calls: setFrame: - {{0, 0}, {320, 109}}
3. setTableHeaderView calls: setFrame: - {{0, 0}, {320, 109}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 109}}
5. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 65}}
6. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 65}}
7. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 65}}
向左旋转设备
1. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {480, 0}}
2. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {480, 0}}
3. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {480, 12}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {480, 12}}
向右旋转设备
1. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 172}}
2. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 172}}
3. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 160}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 160}}
这解释了为什么我的视图最初看起来被截断,然后几乎消失,最后最终与单元格重叠。看来 _resizeWithOldSuperviewSize
是罪魁祸首,我不明白的是为什么调用它以及它从哪里获取这些奇怪的值。
我通过在 viewDidAppear:
和 didRotateFromInterfaceOrientation:
中调用 [self.tableView.tableHeaderView sizeToFit]
来解决这个问题,这将框架放回到尺寸正确,但重绘很糟糕,因为两者都发生在视图可见之后或旋转动画之后。在视图可见之前尝试设置此值会导致 _resizeWithOldSuperViewSize
将框架设置回这些奇怪的尺寸。
I have a custom UIView which I set to the tableHeaderView property of a UITableView during loadView:
headerView = [[MYViewClass alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 120)];
[headerView sizeToFit];
self.tableView.tableHeaderView = headerView;
The view draws incorrectly, with part of the view clipped and white space above the table. When rotating the device the view almost disappears. On rotating back the view is now bigger that the space for the header and obscures some of the cells in the table.
To troubleshoot I have overrode the setFrame method in my custom view class:
- (void) setFrame:(CGRect)frame {
[super setFrame:frame];
NSLog(@"%@ - %@", NSStringFromSelector(_cmd), NSStringFromCGRect(frame));
}
I also put a break point on the NSLog statement so I could see what called the setFrame and I get some odd results that I can't explain and hope someone can shed some light on what is happening and why.
During loadView
1. initWithFrame calls: setFrame: - {{0, 0}, {320, 120}}
2. sizeToFit calls: setFrame: - {{0, 0}, {320, 109}}
3. setTableHeaderView calls: setFrame: - {{0, 0}, {320, 109}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 109}}
5. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 65}}
6. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 65}}
7. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 65}}
Rotating the device left
1. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {480, 0}}
2. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {480, 0}}
3. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {480, 12}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {480, 12}}
Rotating the device right
1. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 172}}
2. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 172}}
3. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 160}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 160}}
Which explains why my view looks truncated initially, then almost disappears and finally ends up overlapping the cells. It appears that _resizeWithOldSuperviewSize
is the culprit and what I don't understand is why it is being called and where it is getting these odd values from.
I have a really rubbish work around by calling [self.tableView.tableHeaderView sizeToFit]
in viewDidAppear:
and didRotateFromInterfaceOrientation:
which puts the frame back to the correct size but the redrawing is awful as both happen after the view is visible or after the rotation animation. Trying to set this anytime before the view is visible causes _resizeWithOldSuperViewSize
to set the frame back to these odd sizes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要获得正确的内在大小和 autoresizingMask 。一旦你这样做了,UITableView 将停止与你的 tableHeaderView 发生冲突。
例如,如果您希望标头具有取决于其内容的固定高度,但希望标头使用整个表格宽度,则可以执行以下操作:
1. 使用以下自动调整大小掩码配置创建视图 (因此表格不会尝试增加标题视图高度):
2. 使用 AutoLayout 添加子视图,使顶部/底部锚点与您的视图匹配(这样子视图就可以定义标题视图的高度)
3. 添加标题视图,如下所示:
You need to get the intrinsic size and autoresizingMask right. Once you do that, UITableView will stop screwing with your tableHeaderView.
For example, if you want your header to have a fixed height which depends on its contents, but you want your header to use the entire table width, this is what you would do:
1.Create your view with the following Autoresizing mask configuration (so the table won't try to increase the header view height):
2. Add your subviews using AutoLayout so the top/bottom anchors match your view (this is so your subviews define the height of your header view)
3. Add your header view like so:
它将帮助您阅读 通过
UIView
的autoresizingMask
属性了解 Apple 的视图调整大小方案。可能的值是:我毫不怀疑,经过一些实验,您会找到正确的调整大小蒙版组合来解决您的问题。
另外,请注意
sizeToFit
,根据相同的文档源“调整大小并移动接收器视图,使其仅包含其子视图”。在创建视图之后并将其放入表头之前调用它似乎不合适。It will help you to read up on Apple's view resizing scheme through the
autoresizingMask
property ofUIView
. Possible values are:I have no doubt that after some experimentation you will find the right resizing mask combination to solve your problem.
Also, please note that
sizeToFit
, according to the same documentation source "resizes and moves the receiver view so it just encloses its subviews." It seems inappropriate to call that just after creating the view and before putting it into the table header.当我想要带有 SearchBar 的表头视图和底部的一些自定义 UI 时,遇到了完全相同的问题。有趣的是,如果你只保留 SearchBar,它就会完美地工作。
所以我决定应用一个非常肮脏的黑客,将自定义 UIView 的重写框架设置器中的框架高度(您正在记录框架大小)重置为您需要的东西(在您的情况下为 120)。
之后,旋转时就不会出现奇怪的标题视图和表格重叠的情况。希望有帮助。
PS 顺便说一句,我在自定义 UIView 中使用自动布局。
Got totally the same problem when I wanted to have table header view with SearchBar and some custom UI at the bottom. The funny thing that if you keep only SearchBar it works just perfect.
So I decided to apply a really dirty hack, reseting Frame's Height in the overridden Frame setter of your custom UIView (there you're logging frame size) to something you need (in your case it's 120).
After that there is no weird header view and table overlapping on rotation. Hope it helps.
P.S. BTW I use Auto Layout inside my custom UIView.
创建一个新的 xib 文件,然后在 xib 文件中自定义您的首选大小。假设 xib 名为 customHeader (.xib) 声明:
将 customView 分配给 xib 中的该视图。
在 .m 中:
然后调用这个 UITableView 方法:
然后最后也是最重要的将回答您的问题!实现另一个 UITableView 方法:
Create a new xib file and then customize your preferred size in the xib file. Say the xib is called customHeader (.xib) Declare:
Assign customView to that view in your xib.
In .m:
Then call this UITableView method:
THEN FINALLY AND MOST IMPORTANT THAT WILL ANSWER YOUR QUESTION! Implement this other UITableView method: