UIPopoverController在pushViewController上自动调整大小到最大高度

时间:2010-08-11 13:25:02

标签: uinavigationcontroller uipopovercontroller

我有一个包含UINavigationController的popover。我可以很好地显示popover,它包含navController就好了。 navController包含一个tableView,当我选择一个项目时,它会创建一个新的详细信息视图:

     DeviceDetailViewController *detailViewController = 
[[[DeviceDetailViewController alloc] initWithNibName:@"DeviceDetailViewController" bundle:nil] autorelease];

然后我把它推到新的视图控制器:

    [self.navigationController pushViewController:detailViewController animated:YES];

这是问题发生的时间: 按下新视图后,弹出窗口会调整为iPad上可用的最大高度。

我尝试将xib中所有视图的高度设置为固定高度而不是灵活。我试过明确设置弹出窗口的高度。我也尝试使用不同的视图控制器作为子视图。问题仍然存在:只要将新视图推送到导航控制器,弹出窗口就希望自动将其自身调整为最大高度。

这是一个question,它讨论了在推送新视图时试图故意控制弹出窗口的大小:

我认为这可能是一种控制大小的蛮力方法。但奇怪的是,它实际上会导致一些快速的图形怪癖(好像视图是刚刚动画的),然后继续调整大小,如上所述。

换句话说,某些东西确实迫使popover达到其最大高度,并且似乎在 所有委托方法被调用之后发生。

是导航控制器吗?有没有人见过这种事?

13 个答案:

答案 0 :(得分:123)

在我遇到同样的问题之后(这也是今天),我已经解决了这个问题:

编辑contentSizeForViewInPopover已弃用iOS7.0,因此请使用preferredContentSize

以下原始答案

detailViewController添加此内容:

- (void)viewWillAppear:(BOOL)animated {

    CGSize size = CGSizeMake(320, 480); // size of view in popover
    self.contentSizeForViewInPopover = size;

    [super viewWillAppear:animated];

}

您还希望添加类似于原始DeviceDetailViewController的内容,以防止在点击后面的NavbarItem时调整大小。

答案 1 :(得分:30)

就像在viewWillAppear中处理它一样,处理此问题的另一种方法是覆盖contentSizeForViewInPopover。非常简洁:

-(CGSize)contentSizeForViewInPopover
{
    return self.view.bounds.size;
}

答案 2 :(得分:30)

对于IOS5

我建议你这样做:

- (void)viewDidLoad {
    [super viewDidLoad];

    CGSize size = CGSizeMake(320, 480); // size of view in popover
    self.contentSizeForViewInPopover = size;

}

答案 3 :(得分:11)

我有类似的问题。

我从工具栏中的按钮出现了弹出窗口。弹出窗口设置为特定大小。这是一个表格视图。选择表格行时,会调用带有导航控制器的新视图控制器。

当选择后退按钮时,弹出窗口变为默认大小(我相信为320x1100),而不是我想要的特定大小。

原始代码是:

  MyTableViewController *myVC = [[MyTableViewController alloc] init];
  UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myVC];

  UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navController];
  popover.delegate = self;

  popover.popoverContentSize = CGSizeMake(400.0, 500.0);

  [myVC release];
  [navController release];
  [popover release];

我添加了一行来解决问题。当然,这是一种解决方法,因为我不得不减去标题的高度。也许你们其中一个人可以用更好的方法来启发我。无论如何,它有效。

  MyTableViewController *myVC = [[MyTableViewController alloc] init];

  UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myVC];

  UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navController];
  popover.delegate = self;

  popover.popoverContentSize = CGSizeMake(400.0, 500.0);

  //Subtract the height of the header to match the total popover size (not just the view).
  myVC.contentSizeForViewInPopover = CGSizeMake(400.0, 500-44);

  [myVC release];
  [navController release];
  [popover release];

我相信当涉及导航控制器并按下后退按钮时,它会使弹出窗口默认为默认大小。通过为视图控制器myVC添加contentSizeForViewInPopover属性,它会强制使用特定的大小。

希望这有用。

库尔特

答案 4 :(得分:9)

对于iOS 7,请使用以下内容:

- (void)viewDidLoad
{
    [super viewDidLoad];

    CGSize size = CGSizeMake(320, 768); // size of view in popover
    self.preferredContentSize = size;
}

UIViewController.contentSizeForViewInPopover已在iOS 7中首先弃用。

答案 5 :(得分:6)

回应带动画的图形故障:

如果您在其中创建带有UINavigationController的弹出窗口,则UIPopoverController动画会与UINavigation控制器动画冲突。在动画制作时会出现图形故障。要解决此问题,请在推送其他控制器或显示工具栏时将动画参数设置为false。

推送视图控制器:

[self.navigationController pushViewController:detailViewController animated:NO];

使工具栏可见:

[[self navigationController] setToolbarHidden:NO animated:NO]; 

设置动画:NO会使动画在UIPopoverController中看起来正确。

答案 6 :(得分:5)

为什么不在将下一个控制器推入导航堆栈之前设置contentSizeForViewInPopover?无需在viewWillAppear等设置尺寸。

[nextController setContentSizeForViewInPopover:[self contentSizeForViewInPopover]];
[[self navigationController] pushViewController:nextController animated:YES];

适用于IOS 5.1

答案 7 :(得分:4)

borked的建议略有不同(这使我指向正确的方向,谢谢!),这就是我在推动新控制器以保持尺寸之前所做的事情:

productViewController.contentSizeForViewInPopover = self.view.bounds.size;
self.contentSizeForViewInPopover = self.view.bounds.size;

[self.navigationController pushViewController:productViewController animated:YES];

我喜欢这个,因为我不必在每个视图控制器中对弹出值进行硬编码(因为我在各种高度使用它们都很好)。

self.contentSizeForViewInPopover行是为了在用户点击时保留大小。我想你可以把这行放在其他地方,比如viewWillAppear或你喜欢的任何地方。

似乎工作......

答案 8 :(得分:2)

在导航中使用的所有视图控制器的 - (void)viewDidLoad中编写代码:

self setContentSizeForViewInPopover:CGSizeMake(320, 500)];

答案 9 :(得分:2)

有两种方法可以在故事板中设置contentSizeForViewInPopover。您可以将使用导航控制器的视图控制器设置为FreeForm,并将根视图设置为所需的大小。或者,您可以将模拟的指标保持为推断,并选中“使用显式尺寸”并设置您想要的尺寸。

然后,在导航控制器中的每个视图控制器中,添加以下内容......

- (void)viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];

     ["yourpopoverController" setPopoverContentSize:CGSizeMake(self.
           contentSizeForViewInPopover.width, seld.contentSizeForViewInPopover.height + self.
           navigationController.navigationBar.frame.size.height) animated:YES];
}

在过渡动画中,新视图将与顶部对齐,然后相应地调整高度。

这样,您不必重写contentSizeForViewInPopover,也不必在视图控制器中指定其他大小。这一切都在故事板中。

如果您的一个视图控制器具有可变高度,那么您需要在该视图中覆盖contentSizeForViewInPopover,如此...

- (CGSize)contentSizeForViewInPopover {
    return CGSizeMake(450, "calculate your height here");
}

答案 10 :(得分:1)

这个东西可能曾经工作过一次但不适用于xCode 6,其中不推荐使用contentSizeForViewInPopover。幸运的是,它在故事板加载时受到尊重。我下载了一个xml编辑器(Xmplify)并破解了故事板。将关键contentSizeForViewInPopover设置为您想要的大小。保存并替换(先制作副本)故事板。

更具体地说:

< viewController>

     <value key="contentSizeForViewInPopover" type="size" width="450" height="280" / >

</viewController>

答案 11 :(得分:0)

当我使用它时,不要为我工作:

[UIPopoverController 
    [UINavigationController] = root vc = [UIViewController vc1] => [UIViewController vc2] 
]
  

当出现popover一切正常时,按vc1上的按钮并将vc2推送到导航控制器

     

接下来返回vc1(root)按下vc2中的按钮(popToRootViewController方法);

     

我们可以看到popover改变了自己的大小,但vc1的大小已经老了......这是什么???

好的,现在正在工作......在我的控制器中添加popover属性

self.contentSizeForViewInPopover = (CGSize){400, 200};
self.navigationController.contentSizeForViewInPopover = self.contentSizeForViewInPopover;
self.popover.popoverContentSize = self.contentSizeForViewInPopover;

答案 12 :(得分:0)

运行Swift 4和iOS 11唯一可行的解​​决方案对我而言。使用showViewController:sender: and showDetailViewController:sender:代替presentViewController:animated:completion:

来自Apple Doc

  

showViewController:sender:和showDetailViewController:sender:methods提供了最自适应和灵活的方式来显示视图控制器。这些方法让呈现视图控制器决定如何最好地处理演示文稿。例如,容器视图控制器可能将视图控制器作为子项合并,而不是以模态方式呈现它。默认行为以模态方式显示视图控制器。