Подтвердить что ты не робот

Анимация popoverContentsize при нажатии контроллера навигационного представления в popover на iPad

Как заставить мой UIPopoverController анимировать его размер, когда его содержащийся UINavigationController выталкивает новый контроллер?

У меня есть UIPopover, отображаемый с UIBarButtonItem в моем приложении для iPad. Он содержит UINavigationViewController, который имеет свое окно настроек в качестве своего контроллера корневого представления. Окно настроек является подклассом UITableViewController (стиль установлен в сгруппированный), а нажатие любой из его ячеек накладывает различные контроллеры вида "chooser" на навигационный контроллер, которые также являются подклассами UITableViewController.

Для каждого из вариантов выбора, в viewDidAppear, я устанавливаю contentSizeForViewInPopover соответствующим образом:

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

Но это не оживляет изменения; когда анимация навигации заканчивается, popover привязывается к новой высоте (ширина никогда не изменяется с 320). Навигация назад назад оживляет изменение размера (выполненное с помощью метода этого ответа), но вперед никогда не делает.

Я попытался получить ссылку на его использование и используя setPopoverContentSize:animated:, но он не работает. Я посмотрел на другие questions безрезультатно.

Как мне заставить его всегда анимировать изменение размера должным образом?

Обновление: Я установил простой тестовый проект, чтобы попробовать это. Это приложение панели вкладок для iPad, настроенное в Xcode. Я добавил элемент панели вкладок в панель навигации в одном из контроллеров представления. Когда эта кнопка нажата, контроллер представляет popover, который содержит контроллер навигации, который имеет очень простой подкласс UITableViewController, называемый TestContentViewController, в качестве своего контроллера корневого представления.

В viewDidLoad этого подкласса я произвольно генерирую несколько элементов:

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

Это мое количество строк; количество разделов равно 1. В cellForRowAtIndexPath я просто установил текст метки ячейки и вернул его. Когда выбрана строка, я создаю другой экземпляр того же класса и вставляю его в стек.

Без каких-либо действий с свойством contentSizeForViewInPopover на любом VC, popover просто достигает максимальной высоты и остается там независимо от того, сколько строк в моем представлении таблицы.

Если я задаю размер в viewDidAppear, вот так:

-(void)viewDidAppear:(BOOL)animated
{
  self.contentSizeForViewInPopover = CGSizeMake(320, self.numItems * 44);
  [super viewDidAppear:animated];
{
  • Когда появляется первый popover, он очень быстро мигает до полной высоты, а затем привязывается к заданной высоте.
  • Когда новый контроллер нажимается на контроллер навигации, он защелкивается до высоты без анимации.
  • Когда я перехожу назад, если VC, который я использую, выше, чем тот, с которого я выхожу, он оживляет нужный размер. Если то, что я использую, меньше, оно ничего не делает.

Если я делаю то же самое, но в viewWillAppear:

  • Когда появится первый popover, он будет полноразмерным
  • Когда я впервые нажимаю строку и получаю новый контроллер в стеке, он оживляет как минимум около 400 пикселей в высоту. Когда новый контроллер помещается в стек, если ему требуется больше высоты, он получает его. Если он не остается прежним,

Если я делаю то же самое в viewDidLoad, он в основном такой же, как viewWillAppear, за исключением того, что он сначала появляется в нужном размере.

Я попытался установить делегат контроллера навигатора в качестве VC, который представляет popover, а затем установите высоту popover (setPopoverContentSize:animated:) в navigationController:didShowViewController:animated:, но результирующая высота немного отключена. Я думаю, что размер, который я установил там, должен учитывать дополнительную высоту навигационной панели, встроенной в верхнюю часть popover. А анимация при нажатии нового контроллера в стеке является странной.

Обновить снова: Смотрите здесь для той же проблемы, которая была решена с помощью нового UIPopoverPresentationController.

4b9b3361

Ответ 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];
}

Ответ 2

Я думаю, вы были близки, если попытались сохранить ссылку на popoverController и использовали setPopoverContentSize:animated:

Что для меня работает, это комбинация setPopoverContentSize:animated: AND contentSizeForViewInPopover в этом конкретном порядке для каждого контроллера, который вы положили в стек:

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

В этом случае self.popoverController - это ссылка, которую я сохраняю в каждом контроллере, который помещается в стек, вероятно, было бы проще использовать для этого одну переменную.

Ответ 3

Если анимация - это то, что вы ищете, вы можете попробовать следующий фрагмент кода. Честно говоря, у меня нет опыта в разработке iPad, но я использую его для анимации кадров и альфа-изменений почти во всех моих проектах. Параметры просты, у вас есть, по порядку, продолжительность, в течение которой происходит анимация, временная задержка, параметры анимации, блок, в котором вы указываете изменения в представлении, и другой объект блока, где вы указываете последствия.

[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) анимированный

Попробуйте и дайте мне знать, если это сработает.