UIPopoverController中使用UINavigationController作为子视图,contentSizeForViewInPopover在父视图上无法工作。

16
我有一个 UIPopoverController,里面包含一个 UINavigationController 子类。父视图和子视图都是 UITableViews。
当我最初使用 contentSizeForViewInPopover = (320,480) 调用父视图时,它的效果非常好。
当我进入子视图并将弹出窗口大小调整为 contentSizeForViewInPopover = (320,780) 时,一切良好。
然而,当我返回到父视图时,我无法使弹出窗口大小重新调整为 contentSizeForViewInPopover = (320,480). 弹出窗口保持在尺寸为 (320,780) 的状态。
我已经尝试了所有方法,但还是有些问题。请问有谁知道如何在上述情况下调整 UIPopoverControllers 的视图大小呢?
谢谢!

有人能帮忙吗?我还是无法正确调整我的弹出窗口大小。增加大小很容易,但我无法将其返回到较小的原始大小。 - Abbacore
好的标签是获得你问题答案的方法 :) - skaffman
6个回答

24

contentSizeForViewInPopover属性仅设置其包含的UIPopoverController的默认(初始)大小。要在任意时间调整UIPopoverController的大小,必须设置它的popoverContentSize属性。请注意,popoverContentSizeUIPopoverController的属性,而不是视图控制器的属性(因此,您可能需要对弹出窗口控制器有一个引用)。

若要每当视图控制器成为UINavigationController的顶部视图控制器时重置弹出窗口的大小,则可以使用UINavigationControllerDelegate协议方法:

navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if (viewController == viewControllerToResize) {
        referenceToUIPopoverController.popoverContentSize = CGSizeMake(320,480);
    }
}

一个潜在的问题是,如果顶层UIViewController的contentSizeForViewInPopover没有设置,并且您设置了UIPopoverController的popoverContentSize,您将首先看到弹出窗口大小为指定的popoverContentSize,然后变为默认大小(当前为320x1100)。为了解决这个问题,我只需设置contentSizeForViewInPopover,然后再设置popoverContentSize。免责声明:这不是一个经过深入研究的发现;而只是我在iOS 4.3上的当前项目中所经历的。 - kalperin
在尝试了几个小时后,这个方法对我起作用了,但在实际调整弹出窗口大小之前,我不得不添加额外的延迟。 - XCool

13

我遇到了同样的问题,但以上解决方案都没有对我起作用。然而,在尝试结合他们的方法时,我受到启发,尝试了一种稍微不同的方法来解决这个问题。这对我很有效:

-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    viewController.contentSizeForViewInPopover = navigationController.topViewController.view.frame.size;
}

我有三个不同的弹出窗口,每个都使用导航视图控制器。这种解决方案的好处在于它适用于所有三个弹出窗口,因为它没有特定地引用任何一个弹出窗口控制器,而是使用当前正在使用的弹出窗口控制器的popoverContentSize属性。


在尝试了这个帖子和其他地方的所有方法之后,这是我让它工作的唯一方法。谢谢。 - Marc M
我在文档中找到了这个内容:“此属性包含视图控制器在弹出窗口中显示时所需的大小。默认情况下,宽度设置为320点,高度设置为1100点。”因此,如果您没有显式地设置contentSizeForViewInPopover,则其大小将为320x1100。这让我很疑惑,因为我认为苹果会使用合理的默认值,并将contentSizeForViewInPopover默认设置为视图的框架或其他什么东西,但显然并非如此。因此,如果您希望您的弹出窗口表现正常,请设置contentSizeForViewinPopover! - mgrandi
这对我也起作用了,但是我不知道为什么。调整弹出窗口的大小似乎有点问题。有时它们会正确地调整大小,而其他时候您必须设置一系列奇怪的方法才能使其正常工作。 - LightningStryk
1
最后,这对我来说是唯一的解决方案,需要做一些修改。首先,要澄清的方法是,您必须将您的UIViewController定义为UINavigationControllerDelegate,并确保将其设置为导航控制器的委托,然后添加所提到的委托方法。我不得不修改我的内容以便它将nav控制器的contentSizeForViewInPopover属性设置为VC的: navigationController.contentSizeForViewInPopover = viewController.contentSizeForViewInPopover; 此外,我确保在创建每个推送的VC时都设置了其contentSizeForViewInPopover属性。 - daver
@daver 将navigationController的属性设置为与视图控制器匹配解决了我的问题。谢谢。 - ChrisH

2
在我的项目中,我需要动态更改弹出窗口的大小。
我将原始控制器委托给我的弹出窗口内容控制器,并实现了它的委托方法,每次更改大小时都会调用该方法:
以下是代码,希望对某些人有所帮助:
-(void) popover:(UIViewController*)controller didChangeSize:(CGSize)size{

    if ([controller class] == [AZViewController class]){
        if (!_popoverController){
            _popoverController = [[UIPopoverController alloc] initWithContentViewController:controller]; 
        }

        _popoverController.popoverContentSize = size;
    }
}

1

我想我可能已经解决了这个问题,因为我已经苦苦挣扎了一段时间。如果这个解决方案对你不起作用,请随时评论。

在每个通过导航层次结构显示的视图控制器中,在viewDidAppear:方法中设置contentSizeForViewInPopover属性为其适当的大小。

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self setContentSizeForViewInPopover:CGSizeMake(320, 320)];
}

我学到的另一件事是,在编辑textField时,当点击返回按钮时,其大小保持不变,而不是变回之前更大的视图。在控制器的viewWillDisappear方法中调用textField的resignFirstResponder方法。

我很好奇这个解决方案是否适用于所有的SDK版本。


1

我认为我曾经遇到过同样的问题,我通过在弹出视图即将出现时设置视图大小来解决它。像这样:

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
self.contentSizeForViewInPopover = CGSizeMake(320, 444); //设置你自己的大小 }

希望这能帮到你。


感谢您的输入,Enrigue。最初我尝试了这个方法,但似乎没有任何效果。想象一下,父级弹出窗口以320x480的大小打开。然后我选择了一行,将一个320x720的“子”视图推入了弹出窗口中。如果我点击返回按钮,我的“父”视图仍然是320x720。 - Abbacore
你能检测到用户何时按下返回按钮或者在他们触摸返回按钮后前一个视图再次显示吗?如果你能检测到,那么你可以将'contentSizeForViewInPopover'放置在代码的那个部分。 - Enrique R.

0

在尝试了许多方法之后,@chuck-k的回答帮助我相当好地解决了iOS7中UINavigationController所带来的弹出窗口困扰。

这是我所做的:

  • 对于UINavigationController中的每个UIViewController,我在方法- (CGSize)contentSizeForViewInPopover中计算我想要显示的内容大小加上navigationController.navigationBar.frame.size.height(我认为始终为44)。我在这些UIViewController中不使用任何其他的弹出窗口功能。

  • 我将创建UINavigationController的UIViewController声明为UINavigationControllerDelegate。

  • 然后在代理中....

.....

- (void)navigationController:(UINavigationController *)navigationController willShowViewController: (UIViewController *)viewController animated:(BOOL)animated {

    BOOL popoverAnimation = NO;

    if ( self.myPopoverController.popoverContentSize.height < viewController.contentSizeForViewInPopover.height ) popoverAnimation = YES;

    [self.myPopoverController setPopoverContentSize:viewController.contentSizeForViewInPopover animated:popoverAnimation];
}

高度检查比较当前视图控制器的弹出内容大小与“传入”的视图控制器的弹出内容大小。当从一个更大的 -> 较小的弹出内容大小转换时,我使用animation = NO,因为否则在iOS7中会得到一些不连贯的重新定位动画。但是奇怪的是,如果从一个较小的 -> 较大的弹出内容大小转换时,popover大小会增加到我预期的大小,但不会显示比先前较小的内容大小更大的content...将animation = YES设置为解决了我的这个问题。(我只检查高度,因为在我的情况下宽度是固定的。)

通过使用这种技术,几乎所有东西最终都能满足我的要求,我希望这可以帮助其他人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接