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


69

我有一个包含UINavigationController的弹出窗口。我可以很好地显示popover,并且其中包含的navController也很好。navController包含一个tableView,当我选择一个项目时,它将创建一个新的详细信息视图:

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

然后,将其推入新的视图控制器:

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

这是发生问题的时间: 推新视图的酥料饼调整大小以在iPad上可用的最大高度。

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

这里有一个问题,其中讨论试图推动新的视图时刻意控制酥料饼的大小:

我认为这可能是控制大小的蛮力方法。不过,奇怪的是,它实际上引起了一些快速的图形怪异现象(就像视图正在重新制作动画一样),然后如上所述继续进行调整大小。

换句话说,某种意义上是在某种程度上迫使弹出框达到最大高度,并且似乎发生了 在调用所有委托方法之后

是导航控制器吗?有没有人看过这种东西?

Answers:


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时调整大小。


4
谢谢!我遇到了同样的问题,UIViewController的contentSizeForViewInPopover属性修复了它。
Titandecoy 2010年

谢谢您,您保存了我的一天:D
Yildiray Meric 2010年

2
在至少一种情况下,我仍然必须自己明确设置弹出窗口的高度(如果弹出窗口控制器已经可见且具有定义的高度)。否则,这可以用于返回导航控制器中的上一页。
Kendall Helmstetter Gelner 2011年

哇!这很难找到。非常感谢。这确实有帮助。如果手动旋转弹出窗口中的视图控制器,则所有推入的视图控制器都会更改其大小。使用此替代方法可使一切顺利。我正在寻找Days,以寻求这样的解决方案。
JackPearse 2011年

1
这对我不起作用,需要将其放入viewDidLoad中,而不是viewWillAppear中
daidai 2013年

30

就像处理它一样viewWillAppear,另一种处理方法是重写contentSizeForViewInPopover。非常简洁:

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

可与iOS5一起使用。borked解决方案似乎不适用于ios5。
palaniraja 2012年

1
以我为例,这只是使弹出框的大小等于整个屏幕的大小。
Greg Maletic

@Greg Maletic,self.view您的观点是哪个?我只是再次测试了一下,它仍然有效。
彼得·德威斯

@PeterDeWeese看到该属性的标题:contentSizeForViewInPopover允许您从视图控制器中设置内容的大小。此属性是读/写,通常不应覆盖它
直到2012年

@Till仍然在contentViewController上设置该属性viewWillAppear对我没有用,而覆盖getter总是起作用。
A-Live

30

对于IOS5

我建议您在以下方面进行操作:

- (void)viewDidLoad {
    [super viewDidLoad];

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

}

这对我不起作用,弹出视图控制器并不会恢复该控制器的高度,尽管它确实会恢复该控制器的正确宽度。请查看我的公开回购,bitbucket.org/danielphillips/uipopovercontroller
Daniel

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属性,它将强制使用特定大小。

希望这会有所帮助。

库尔特


当我在已经调整大小的弹出式控制器中将现有的视图控制器替换为新的视图控制器时,其他选项不起作用,此选项确实起作用
Yogev Shelly 2012年

9

对于iOS 7,请使用以下命令:

- (void)viewDidLoad
{
    [super viewDidLoad];

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

UIViewController.contentSizeForViewInPopover 在iOS 7中已被弃用。


6

响应动画中的图形故障:

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

推送视图控制器:

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

使工具栏可见:

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

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


UIPopoverController和[UINavigationController setToolbarHidden:animated:]之间的动画冲突是我面临的一个问题。好的提示,因为修复不直观。如您所说,没有动画的setToolbarHidden实际上将显示/隐藏带有由UIPopoverController处理的动画的工具栏。非常微妙但令人讨厌的陷阱。
克里斯·迈尔斯

5

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

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

在IOS 5.1上工作


1
contentSizeForViewInPopover在iOS7中已弃用,但preferredContentSize效果也不错。
里根·萨瓦斯

4

对borked的建议略有不同(这向我指出了正确的方向,谢谢!),这是我在推新控制器以保持尺寸之前所做的工作:

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

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

我之所以这样,是因为我不必在每个视图控制器中都对popover值进行硬编码(很好,因为我在不同的高度使用了它们)。

self.contentSizeForViewInPopover行是为了保留用户回弹时的大小。我想你可以把这条线放在其他地方,例如viewWillAppear或地方。

似乎可以工作...


2

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

self setContentSizeForViewInPopover:CGSizeMake(320, 500)];

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");
}

1

这些东西可能只工作过一次,但不适用于xCode 6,其中不推荐使用contentSizeForViewInPopover。幸运的是,在情节提要加载时受到了尊重。我下载了一个XML编辑器(Xmplify)并破解了情节提要。将关键contentSizeForViewInPopover设置为所需的大小。保存并替换(首先复制)情节提要。

进一步来说 :

< viewController>

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

</viewController>

0

当我使用此功能时,请不要为我工作:

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

当出现弹出窗口都很好时,请按vc1上的按钮,然后将vc2推入导航控制器

接下来返回vc1(根目录)并按下vc2中的按钮(popToRootViewController方法);

我们可以看到popover更改了自己的大小,但是vc1的大小却很旧...这是什么???

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

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

0

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

从Apple Doc

showViewController:sender:和showDetailViewController:sender:方法提供了显示视图控制器的最灵活,最灵活的方法。这些方法使演示视图控制器可以决定如何最好地处理演示。例如,容器视图控制器可以将视图控制器作为子级合并,而不是模态地呈现。默认行为以模态形式显示视图控制器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.