UIPopoverController 的大小调整行为在 iOS 7.0 和 iOS 7.1 之间有所不同

Posted

技术标签:

【中文标题】UIPopoverController 的大小调整行为在 iOS 7.0 和 iOS 7.1 之间有所不同【英文标题】:Resizing behavior of UIPopoverController differs between iOS 7.0 and iOS 7.1 【发布时间】:2014-03-28 10:40:10 【问题描述】:

我有一个 UIPopoverController,它在 UINavigationController 中包含一个 UITableViewController。 每当按下此表格视图中的一个单元格时,我都会将另一个 UITableViewController 推送到我的导航控制器。

我想设置我的第二个表格视图的高度(假设为 200)并相应地调整弹出框的大小。

因此,我首先在viewDidAppear:(BOOL)animated 中设置表格视图框架,然后调用setPopoverContentSize:(CGSize)size animated:(BOOL)animated。两个高度都设置为 200。

调整大小有效,但不同ios版本存在以下差异:

iOS 6.1

如预期:调整大小的弹出框的高度为 200 + 导航栏的高度。

iOS 7.0

不符合预期:调整大小的弹出框高度为 200,包括导航栏的高度。

iOS 7.1

如预期:调整大小的弹出框的高度为 200 + 导航栏的高度。 由于某种原因,调整大小是动画的,表格视图很快显示在导航栏后面。

我可以忍受不同的高度,因为这些高度可以根据 iOS 版本进行调整。不过,我不喜欢丑陋的动画。你知道我如何在没有这个故障的情况下实现我的目标吗?

下面是我要避免的效果截图:

下面是我如何创建 UIPopoverController:

- (IBAction)showPopup:(id)sender

    MyTableViewController *table = [[MyTableViewController alloc] initWithStyle:UITableViewStylePlain];

    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:table];
    nav.navigationBar.tintColor = [UIColor orangeColor];

    UIPopoverController *pop = [[UIPopoverController alloc] initWithContentViewController:nav];

    table.parentPopover = pop;

    UIView *origin = (UIView *)sender;
    CGRect buttonRect = CGRectMake(origin.frame.origin.x, origin.frame.origin.y, origin.frame.size.width, origin.frame.size.height);
    [pop presentPopoverFromRect:buttonRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

当一个表格单元被按下时,我推动另一个表格视图控制器:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];

    MyNextTableViewController *next = [[MyNextTableViewController alloc] initWithStyle:UITableViewStylePlain];
    next.parentPopover = self.parentPopover;
    [self.navigationController pushViewController:next animated:YES];

这是我调整“最终”表格视图和弹出框大小的方法:

- (void)viewDidAppear:(BOOL)animated

    [super viewDidAppear:animated];
    self.tableView.frame = CGRectMake(0, 0, self.tableView.frame.size.width, 200);
    [self.parentPopover setPopoverContentSize:[self contentSizeForViewInPopover] animated:NO];


- (CGSize)contentSizeForViewInPopover

    return CGSizeMake(320, self.tableView.frame.size.height);

顺便说一句,我知道- (CGSize)contentSizeForViewInPopover 从iOS 7.0 开始已被弃用,但我想支持iOS 6,并且在使用- (CGSize)preferredContentSize 时也会出现上述问题。 UIScrollView 也有同样的问题,不仅仅是 UITableView。

编辑: 我向 Apple 提交了错误报告,错误号为 16865330。

【问题讨论】:

【参考方案1】:

这是 iOS7 及更高版本的弹出框控制器中的一个错误。请在https://bugreport.apple.com 中向 Apple 提交错误报告,并在您的问题中发布错误编号。

这是由于在viewDidAppear 中调整弹出框控制器的大小而发生的。关键是稍微延迟调整大小,以便弹出框控制器可以完成其布局。在主队列上使用dispatch_async,您注册您的块以在主运行循环的后续通道上运行,这使弹出控制器有足够的时间“繁殖”并且不会重现错误。

- (void)viewDidAppear:(BOOL)animated

    [super viewDidAppear:animated];
    self.tableView.frame = CGRectMake(0, 0, self.tableView.frame.size.width, 200);

    dispatch_async(dispatch_get_main_queue(), ^
        [self.parentPopover setPopoverContentSize:[self contentSizeForViewInPopover] animated:NO];
    );

【讨论】:

感谢您的帮助,这暂时解决了问题。我将在接下来的几天内向 Apple 提交错误报告,并在此处发布错误编号。

以上是关于UIPopoverController 的大小调整行为在 iOS 7.0 和 iOS 7.1 之间有所不同的主要内容,如果未能解决你的问题,请参考以下文章

当我调整它的大小时 UIPopoverController 移动

UIPopoverController 的大小调整行为在 iOS 7.0 和 iOS 7.1 之间有所不同

UIPopovercontroller 在将新的视图控制器推送到 navccontroller 后调整大小

在 uipopovercontroller 中推送一个新的 tableViewController 会导致调整弹出框的大小

UIPopoverController w/MonoTouch.Dialog 会导致不需要的弹出框大小调整

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