弹出框内容视图的额外高度

Posted

技术标签:

【中文标题】弹出框内容视图的额外高度【英文标题】:Extra height of popover's content view 【发布时间】:2013-05-24 17:49:47 【问题描述】:

我用UITableViewController 打开UIPopoverController 弹出框,因为它是内容视图控制器。

Popover 的大小合适,乍一看它的内容视图调整正确,但如果我尝试在 popover 内滚动,它会滚动,尽管它不应该滚动。似乎在 -(void)viewDidAppear (图 1、2)之后,内容视图会高出约 20 px。 我该怎么做才能检查尺寸:

- (void)viewDidAppear:(BOOL)animated

    NSLog(@"%@", self.view);

输出是

Popovers[3016:c07] <UITableView: 0x10b80600; frame = (0 0; 200 66); autoresize = W+H; gestureRecognizers = <NSArray: 0x1004cc20>; layer = <CALayer: 0x1004c4a0>; contentOffset: 0, 0>

此时大小正确,等于popover的大小。打开弹出框后,它的无边距内部尺寸为 66 像素(在 Ruler 应用程序的帮助下测量)。因此,它似乎应该完全适合内容视图的大小。但是以某种方式出现了意外的垂直滚动。

比,如果我将 20 像素添加到弹出框的高度, [mOptionPopoverController setPopoverContentSize:(CGSize)200, 86]; 比它的内容视图也增加并符合预期,没有任何滚动条。唯一的问题是我不需要在弹出框底部空 20 像素(图 3)。

我做了一个小测试项目来重现我的问题。这是重要的代码:

@implementation ViewController

- (IBAction)buttonPressed:(id)sender

    TableViewController *popoverViewController = [[TableViewController alloc] initWithStyle:UITableViewStyleGrouped];
    UIPopoverController* mOptionPopoverController = [[UIPopoverController alloc] initWithContentViewController:popoverViewController];
    [mOptionPopoverController setPopoverContentSize:(CGSize)200, 66]; 
    CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
    [mOptionPopoverController presentPopoverFromRect:popoverRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];


@end

@implementation TableViewController

- (id)initWithStyle:(UITableViewStyle)style

    self = [super initWithStyle:style];
    if (self) 
        self.tableView.bounces = NO;
    
    return self;


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    return 1;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

    return cell;


- (void)viewDidAppear:(BOOL)animated

    NSLog(@"%@", self.view);


@end

图片.1

图 2

图 3

这是我所期望的:

UPD。

我已经做了进一步的调查。 我使用 KVO 来跟踪帧的变化。我期待它会帮助找到有用的东西。我发现了一些东西,但并没有让事情变得更清楚。

所以,我在TableViewController的- (id)initWithStyle:(UITableViewStyle)style方法中添加了[self.view addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];,观察方法为

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

    NSLog(@"%@", [object valueForKeyPath:keyPath]);

这是输出:

2013-05-27 15:52:12.755 Popovers[1547:c07] NSRect: 0, 0, 200, 84
2013-05-27 15:52:12.756 Popovers[1547:c07] NSRect: 0, 0, 200, 84
2013-05-27 15:52:12.756 Popovers[1547:c07] NSRect: 0, 0, 200, 66
2013-05-27 15:52:12.759 Popovers[1547:c07] <UITableView: 0x9337600; frame = (0 0; 200 66); autoresize = W+H; gestureRecognizers = <NSArray: 0x8949760>; layer = <CALayer: 0x8944690>; contentOffset: 0, 0>

(最后一个来自- (void)viewDidAppear:(BOOL)animated)。

为什么是 84?这是84-66=18,这些不是我要找的那些 20 像素。 此外,观察者方法的所有三个调用都发生在调用 tableView 数据源方法之前。在 tableView 构建之前如何知道框架?

(我目前使用@robmayoff tableView.scrollEnabled = NO; 建议的问题太多,以抑制不必要的弹出窗口。)

UPD。 甚至 Apple 系统打印弹出框在打印机选择列表中也有 20 像素和不必要的滚动条。

【问题讨论】:

您是否尝试过简单地设置popoverViewController.tableView.scrollEnabled = NO?我知道这并不能解释您遇到问题的原因,但它应该可以防止它。 @robmayoff 谢谢你的想法。我试过了,它真的没有滚动条了。如果没有更好的建议,我将使用此解决方法。 你的 UITableView 的配置是什么?没有 20 像素的页眉或页脚,或者有什么好玩的东西吗? @MikePollard 它是由 1 个部分组成的分组表视图。它仅使用代码,如上所示。如果我尝试在 -(void)viewDidAppear 中记录页眉、行和页脚高度,我会收到输出 header: 10.000000 row: 46.000000 footer: 10.000000。正是66。我不知道还有什么可能是额外身高的原因。 【参考方案1】:

这显然是 Apple Bug,因为这个问题在 WWDC 2013 期间被苹果工程师问过,但没有得到答案。

解决方法是

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section

    return 0.1f;

【讨论】:

【参考方案2】:

尝试如下设置表格视图的滚动启用属性。

tableView.scrollEnabled = NO;

【讨论】:

谢谢,我按照我的问题的第一条评论中的建议尝试了它,它有效,但不幸的是它没有解释问题的原因。

以上是关于弹出框内容视图的额外高度的主要内容,如果未能解决你的问题,请参考以下文章

在缩小弹出框的内容大小时防止伪影

初始化后直接释放内容视图控制器的弹出框

当作为弹出框触发时更改 MasterViewController 的大小

隐藏弹出框控制器

UIPopoverController 以不同的速度调整弹出框和内容视图控制器(uinavigationcontroller)的大小

弹出框的最大尺寸