【问题标题】:Animate popoverContentsize when pushing navigation view controller in popover on iPad在 iPad 上的弹出窗口中推送导航视图控制器时动画 popoverContentsize
【发布时间】:2012-09-18 07:41:20
【问题描述】:

当我的 UIPopoverController 包含的 UINavigationController 推送一个新的控制器时,如何让我的 UIPopoverController 为其大小设置动画?

我的 iPad 应用程序中的 UIBarButtonItem 显示了 UIPopover。它包含一个UINavigationViewController,它有一个设置窗口作为它的根视图控制器。设置窗口是UITableViewController 的子类(样式设置为分组),点击它的任何单元格都会在导航控制器上推送不同的“选择器”视图控制器,它们也是UITableViewController 的子类。

对于每个选择器视图,在viewDidAppear 中,我正在适当地设置contentSizeForViewInPopover:

self.contentSizeForViewInPopover = CGSizeMake(320, self.items.count * 44);

但它不会使变化产生动画;当导航动画结束时,弹出框会捕捉到新的高度(宽度永远不会从 320 改变)。向后导航会为大小变化设置动画(使用this answer 中的技术完成),但向前导航不会。

我尝试获取对它所在的弹出框的引用并使用setPopoverContentSize:animated:,但它不起作用。我查看了other questions 无济于事。

如何让它始终正确地为大小变化设置动画?

更新:我已经建立了一个简单的测试项目来试试这个。这是在 Xcode 中设置的 iPad 的标签栏应用程序。我在其中一个视图控制器的导航栏中添加了一个标签栏项目。当按下该按钮时,控制器会显示一个弹出框,其中包含一个导航控制器,该控制器有一个非常简单的UITableViewController 子类,称为TestContentViewController,作为其根视图控制器。

在那个子类的viewDidLoad中,我随机生成了一些项目:

self.numItems = arc4random() % 10 + 3;

这是我的行数;节数为 1。在cellForRowAtIndexPath 中,我只是设置了单元格的标签文本并返回它。选择行时,我生成同一类的另一个实例并将其推在堆栈上。

无需对任何 VC 上的 contentSizeForViewInPopover 属性执行任何操作,无论我的表格视图中有多少行,弹出框都会达到其最大高度并保持在那里。

如果我在 viewDidAppear 中设置大小,像这样:

-(void)viewDidAppear:(BOOL)animated
{
  self.contentSizeForViewInPopover = CGSizeMake(320, self.numItems * 44);
  [super viewDidAppear:animated];
{
  • 当弹出框第一次出现时,它会非常快速地闪烁到全高,然后迅速恢复到我设置的高度。
  • 当一个新的控制器被推到导航控制器上时,它会在没有动画的情况下捕捉到它的高度。
  • 当我向后导航时,如果我要弹出的 VC 比我要弹出的那个高,它会以正确的大小进行动画处理。如果我弹出的内容更小,它什么也不做。

如果我做同样的事情但在viewWillAppear:

  • 当弹出框第一次出现时,它是全高的
  • 当我第一次点击一行并在堆栈中获得一个新控制器时,它的动画高度至少约为 400 像素。当一个新的控制器被压入堆栈时,如果它需要更多的高度,它就会得到它。如果不是,它会保持以前的状态。

如果我在viewDidLoad 中做同样的事情,它基本上与viewWillAppear 相同,只是它首先以正确的大小显示。

我尝试将导航控制器的委托设置为呈现弹出框的 VC,然后在 navigationController:didShowViewController:animated: 中设置弹出框的高度 (setPopoverContentSize:animated:),但结果高度有一点偏差。我认为我在那里设置的大小需要考虑到内置于弹出框顶部的导航栏的额外高度。而且将新控制器压入堆栈时的动画很奇怪。

再次更新:请参阅here,了解使用较新的UIPopoverPresentationController 解决的相同问题。

【问题讨论】:

  • @Jefferson,必须尝试将导航控制器的 popoverContentSize 设置为 Popover 的 contentViewController 吗?
  • @8Ours - 是的,我刚刚尝试过,当新的 VC 被推到导航控制器上时,它会使弹出框达到最高高度。没有运气。

标签: ios ipad uitableview uipopovercontroller


【解决方案1】:

尝试对所有 UITableViewController 执行以下操作,我试过了,它对我有用!

- (void)setSize:(BOOL)fake
{
    CGSize view_size;
    int sections_height, rows_height;

    //if you dynamically change the number of visible rows
    //for example overriding numberOfRowsInSection:section
    //this can help you to evaluate the correct popover height
    int sections = [self.tableView numberOfSections];
    int rows = 0;
    for(int i = 0; i < sections; i++){
        rows += [self.tableView numberOfRowsInSection:i];
    }
    sections_height = sections * 30 /*section height*/;
    rows_height = rows * 44 /*row height*/;

    view_size = CGSizeMake(320 /*fixed width*/, sections_height + rows_height);

    if(fake){
        view_size.width -= 1;
        view_size.height -= 1;
    }

    [self setContentSizeForViewInPopover:view_size];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    //...    
    [self setSize:FALSE];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self setSize:TRUE];
}

- (void)viewDidAppear:(BOOL)animated
{
    [self setSize:FALSE];
    [super viewDidAppear:animated];
}

【讨论】:

  • 这似乎有效。不过,我不得不根据我的具体情况稍微修改数学。
  • @Mr.Jefferson 你认为我应该得到奖励吗? :)
  • 等待日本。如果他的解决方案最终奏效,那就更清洁了。如果没有,那都是你的。
  • 不得不以这种方式完成令人惊讶,但您的解决方案对我来说效果很好。
【解决方案2】:

如果您尝试保留对 popoverController 的引用并使用 setPopoverContentSize:animated:,我认为您已经接近了

对我有用的是 setPopoverContentSize:animated: 和 contentSizeForViewInPopover 按特定顺序的组合,对于您放入堆栈的每个控制器:

-(void)viewDidAppear:(BOOL)animated
{
    [self.popoverController setPopoverContentSize:whateverSize animated:true];
    self.contentSizeForViewInPopover = whateverSize;
    [super viewDidAppear:animated];
}

在这种情况下,self.popoverController 是我在每个压入堆栈的控制器中保留的引用,为此使用单例变量可能会更简洁。

【讨论】:

  • 我试过了,看起来表格视图动画到了适当的高度,但弹出框本身仍然捕捉到新的高度。
  • 那么它一定是您的项目特定的东西,您有我们可以解决的示例项目吗?我使用上面的代码创建了一个示例项目,并且我的弹出框正在调整动画大小
  • 我在一个示例项目中尝试过这个,但我不知道在哪里发布以供下载。
  • 我可能不明白这个问题,或者我们没有使用相同的 iOS 版本(我使用的是 iOS6),但我运行了你的代码,并且每次我运行时弹出框都会动画到新的高度正在按一行或按返回上一级..
【解决方案3】:

如果你想要的是动画,你可以试试下面这段代码。老实说,我没有 iPad 开发经验,但我几乎在所有项目中都用它来动画帧和 alpha 变化。 参数很简单,依次是动画发生的持续时间、时间延迟、动画选项、指定视图更改的块以及指定后果的另一个块对象。

[UIView animateWithDuration:1.0
                      delay:0.0
                    options: UIViewAnimationCurveEaseOut
                 animations:^{
               self.contentSizeForViewInPopover = CGSizeMake(320, self.items.count * 44);
                 }
                 completion:^(BOOL finished){
                //Insert what you need to do after the animation is over
                 }];

你可以试试把它放在-(void)viewDidAppear:(BOOL)animated

试试看,如果有效,请告诉我。

【讨论】:

  • 此动画代码更多用于自定义动画;我正在尝试让系统执行自己的动画。
  • 哦,好的。就像我说的,真的不是 iPad 开发者。但很高兴你从 Francesco Vadicamo 那里得到了答案。
猜你喜欢
  • 1970-01-01
  • 2014-12-09
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
  • 2014-02-21
  • 1970-01-01
相关资源
最近更新 更多