带嵌入式导航控制器的Popover不支持背面导航的尺寸

Ben*_*tto 88 uiviewcontroller uinavigationcontroller uipopovercontroller ios

我有一个托管UINavigationController的UIPopoverController,它包含一个小的视图控制器层次结构.

我按照文档和每个视图控制器,我设置了视图的popover-context大小,如下所示:

[self setContentSizeForViewInPopover:CGSizeMake(320, 500)];
Run Code Online (Sandbox Code Playgroud)

(每个控制器的大小不同)

当我在层次结构中向前导航时,这可以正常工作 - 弹出窗口自动动画大小更改以对应于推送的控制器.

但是,当我通过导航栏的"后退"按钮通过视图堆栈"返回"时,弹出窗口不会改变大小 - 它仍然与最深的视图一样大.这似乎对我不利; 我希望popover能够尊重弹出视图堆栈时设置的大小.

我错过了什么吗?

谢谢.

kra*_*nyk 93

好吧,我正在努力解决同样的问题.以上解决方案都不适合我,这就是为什么我决定做一些调查并找出它是如何工作的原因.这就是我发现的: - 当您contentSizeForViewInPopover在视图控制器中设置它时,弹出窗口本身不会更改它 - 即使弹出窗口大小可能会在导航到不同控制器时发生变化. - 当导航到不同控制器时弹出窗口的大小会发生变化,同时返回时,弹出窗口的大小不会恢复 - 在viewWillAppear中更改弹出窗口的大小会产生非常奇怪的动画(当我们在弹出窗口中说popBtroller时) - 我不推荐它 - 对我来说,设置控制器内部的硬编码大小根本不起作用 - 我的控制器有时候很大,有时候很小 - 控制器会让他们有关于大小的想法虽然

所有痛苦的解决方案如下:您必须重置currentSetSizeForPopoverviewDidAppear 的大小.但是你必须要小心,当你设置与现场设置相同的大小时,currentSetSizeForPopover弹出窗口不会改变大小.为此,您可以首先设置假大小(与之前设置的大小不同),然后设置适当的大小.即使您的控制器嵌套在导航控制器内,此解决方案也会起作用,当您在控制器之间导航时,弹出窗口将相应地更改其大小.

您可以使用以下帮助方法在UIViewController上轻松创建类别,该方法可以设置大小:


- (void) forcePopoverSize {
    CGSize currentSetSizeForPopover = self.contentSizeForViewInPopover;
    CGSize fakeMomentarySize = CGSizeMake(currentSetSizeForPopover.width - 1.0f, currentSetSizeForPopover.height - 1.0f);
    self.contentSizeForViewInPopover = fakeMomentarySize;
    self.contentSizeForViewInPopover = currentSetSizeForPopover;
}
Run Code Online (Sandbox Code Playgroud)

然后只需在-viewDidAppear所需的控制器中调用它.

  • 我把它包装在[UIView beginAnimations:nil context:nil]中; 和[UIView commitAnimations]; - 使它不那么刺耳. (2认同)
  • 对我来说,使用self.contentSizeForViewInPopover = CGSizeZero; 保存了一条线并产生了同样的效果.非常感谢! (2认同)

Wes*_*man 18

以下是我为iOS 7和8解决的问题:

在iOS 8中,iOS默认将您想要的视图包装在presentViewController视图控制器的presentViewController中.2014年的WWDC视频解释了popovercontroller的新功能.

无论如何,对于导航控制器堆栈上显示的所有想要自己调整大小的视图控制器,这些视图控制器需要(在iOS 8下)调用此代码来动态设置preferredContentSize:

self.presentingViewController.presentedViewController.preferredContentSize = CGSizeMake(320, heightOfTable);
Run Code Online (Sandbox Code Playgroud)

将heightOfTable替换为您的计算表或视图高度.

为了避免大量重复的代码并创建一个通用的iOS 7和iOS 8解决方案,我在UITableViewController上创建了一个类别,以便在我的tableviews中调用viewDidAppear时执行此工作:

- (void)viewDidAppear:(BOOL)animated 
{
    [super viewDidAppear:animated];
    [self setPopOverViewContentSize];
}
Run Code Online (Sandbox Code Playgroud)

Category.h:

#import <UIKit/UIKit.h>

@interface UITableViewController (PreferredContentSize)

- (void) setPopOverViewContentSize;

@end
Run Code Online (Sandbox Code Playgroud)

Category.m:

#import "Category.h"

@implementation UITableViewController (PreferredContentSize)

- (void) setPopOverViewContentSize
{
    [self.tableView layoutIfNeeded];
    int heightOfTable = [self.tableView contentSize].height;

    if (heightOfTable > 600)
        heightOfTable = 600;

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0)
            self.preferredContentSize=CGSizeMake(320, heightOfTable);
        else
            self.presentingViewController.presentedViewController.preferredContentSize = CGSizeMake(320, heightOfTable);
    }
}

@end
Run Code Online (Sandbox Code Playgroud)


adn*_*ako 12

这是对krasnyk答案的改进.
你的解决方案很棒,但它并不是很流畅.
一点点改进给出了很好的动画:

删除- (void) forcePopoverSize方法中的最后一行:

- (void) forcePopoverSize {
    CGSize currentSetSizeForPopover = self.contentSizeForViewInPopover;
    CGSize fakeMomentarySize = CGSizeMake(currentSetSizeForPopover.width - 1.0f, currentSetSizeForPopover.height - 1.0f);
    self.contentSizeForViewInPopover = fakeMomentarySize;
}
Run Code Online (Sandbox Code Playgroud)

将[self forcePopoverSize]放在- (void)viewWillAppear:(BOOL)animated方法中:

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

    [self forcePopoverSize];
}
Run Code Online (Sandbox Code Playgroud)

最后 - 在- (void)viewDidAppear:(BOOL)animated方法中设置所需的大小:

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

    CGSize currentSetSizeForPopover = self.contentSizeForViewInPopover;
    self.contentSizeForViewInPopover = currentSetSizeForPopover;
}
Run Code Online (Sandbox Code Playgroud)


Mad*_*dav 8

您需要再次设置内容大小viewWillAppear.通过调用delagate方法,在其中设置popovercontroller的大小.我也有同样的问题.但当我添加这个问题时,问题就解决了.

还有一件事:如果你使用的是小于5的beta版本.那么弹出窗口就更难管理了.从beta版本5开始,它们似乎更加友好.最终版本已经出局了.;)

希望这可以帮助.

  • 在`viewWillAppear`中设置内容大小对我来说不起作用.明确地设置popover的大小确实有效,但那是贫民窟. (2认同)

Sum*_*diq 5

-(void)viewDidLoad导航控制器中使用的所有视图控制器中,添加:

[self setContentSizeForViewInPopover:CGSizeMake(320, 500)];
Run Code Online (Sandbox Code Playgroud)