UIPopoverController автоматическое изменение размера до максимальной высоты на pushViewController


у меня есть поповер, содержащий UINavigationController. Я могу отобразить popover отлично, и он содержит navController просто отлично. NavController содержит tableView, и когда я выбираю элемент, он создает новый подробный вид:

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

затем я нажимаю на него новый контроллер вида:

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

это когда возникает проблема:после нажатие на новый вид popover изменяет размер до максимальной высоты, доступной на экране устройство iPad.

Я попытался установить высоту всех представлений в xib на фиксированную высоту, а не гибкую. У меня явно попытался установить высоту диалогового окна. Я также попытался использовать различные контроллеры представления в качестве дочернего представления. Проблема остается: пирог хочет чтобы автоматически изменять размер до максимальной высоты при каждом нажатии нового представления на навигационный контроллер.

вот вопрос, который обсуждает попытку сознательно контролировать размер всплывающего окна при нажатии новых представлений:

Я думал, что это может быть методом грубой силы, чтобы контролировать размер. Как ни странно, однако, это на самом деле вызывает некоторые быстрые графические причуды (как будто вид был недавно анимирован), а затем продолжает изменять размер, как описано выше.

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

это навигационный контроллер? Кто-нибудь видел подобное?

13 68

13 ответов:

это исправило его для меня после того, как у меня была та же проблема (по совпадению и сегодня):

EDIT : как 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.

очень нравится обрабатывать его в viewWillAppear, другой способ справиться с этим-переопределить contentSizeForViewInPopover. Очень лаконично:

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

для IOS5

Я рекомендую вам сделать это:

- (void)viewDidLoad {
    [super viewDidLoad];

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

}

у меня была аналогичная проблема.

у меня был пирог подарок от кнопки на панели инструментов. Этот пирог был задан определенный размер. Это был вид из таблицы. При выборе строки таблицы вызывался новый контроллер вида с навигационным контроллером.

когда кнопка назад была выбрана, поповер стал размером по умолчанию (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];

Я считаю, что когда задействован навигационный контроллер и нажата кнопка "назад", это приводит к тому, что popover по умолчанию имеет размер по умолчанию. Добавляя свойство contentSizeForViewInPopover для контроллера вида myVC, он вызывает определенный размер.

надеюсь, что это полезный.

Курт

для iOS 7 используйте следующее:

- (void)viewDidLoad
{
    [super viewDidLoad];

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

UIViewController.contentSizeForViewInPopover был устаревшим сначала в iOS 7.

в ответ на графические глюки с анимацией:

анимации UIPopoverController конфликтуют с анимациями контроллеров UINavigation, если вы создаете popover с UINavigationController внутри него. Это приводит к графическим сбоям при анимации. Чтобы устранить эту проблему, установите для параметра animated значение false при нажатии других контроллеров или при отображении панели инструментов.

Нажатие Контроллеров Вида:

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

сделать панель инструментов видимой:

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

установка анимированного: нет сделает анимацию выглядеть правильно в UIPopoverController.

почему бы просто не установить contentSizeForViewInPopover прежде чем вы нажмете следующий контроллер в стек навигации? Нет необходимости устанавливать размеры viewWillAppear и так далее.

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

работает на IOS 5.1

незначительный вариант по совету неисправен (который указал мне в правильном направлении, Спасибо!), вот что я делаю, когда нажимаю новый контроллер для поддержания размера перед его нажатием:

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

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

мне это нравится, потому что мне не нужно жестко кодировать значения popover в каждом контроллере вида (хорошо, так как я использую их на разных высотах).

The self.contentSizeForViewInPopover линия для сохранения размера, когда пользователь нажимает назад. Я думаю, вы могли бы поставить эту линию где-нибудь иначе, как viewWillAppear или где угодно.

кажется, работает...

в - (void)viewDidLoad всех контроллеров вида, которые вы используете в навигации, напишите код:

self setContentSizeForViewInPopover:CGSizeMake(320, 500)];

есть два способа установить contentSizeForViewInPopover в раскадровке. Вы можете настроить контроллеры представлений, которые находятся в вашем навигационном контроллере, на свободную форму и установить корневые представления на нужный размер. Или вы можете сохранить смоделированную метрику как выведенную и проверить "использовать явный размер" и установить размер, который вы хотите там.

затем в каждом контроллере вида, который находится в вашем навигационном контроллере, добавьте следующее...

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

этот материал, возможно, работал один раз, но не с xCode 6, где contentSizeForViewInPopover является устаревшим. К счастью, это уважается во время загрузки раскадровки. Я загрузил редактор xml (Xmplify) и взломал раскадровку. Установите ключ contentSizeForViewInPopover в нужный размер. Сохраните и замените (сначала сделайте копию) раскадровку.

более конкретно :

< viewController>

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

</viewController>

Не работайте на меня, когда я использую это:

[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;

запуск Swift 4 и iOS 11 единственное возможное решение было для меня. Использовать showViewController:sender: and showDetailViewController:sender: вместо presentViewController:animated:completion:.

от Apple Doc

showViewController:sender: и showDetailViewController:sender: методы предлагают наиболее адаптивный и гибкий способ отображения контроллеров представления. Эти методы позволяют контроллеру представления представления решить, как лучше всего обрабатывать презентацию. Например, контроллер вида контейнера может включать контроллер вида в детстве вместо того, чтобы представить его модально. Поведение по умолчанию представляет контроллер представления модально.