UIPopoverController автоматически изменяет размер до максимальной высоты на pushViewController - PullRequest
68 голосов
/ 11 августа 2010

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

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

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

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

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

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

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

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

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

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

Ответы [ 13 ]

123 голосов
/ 11 августа 2010

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

РЕДАКТИРОВАТЬ : поскольку 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.

30 голосов
/ 14 октября 2011

для IOS5

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

- (void)viewDidLoad {
    [super viewDidLoad];

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

}
30 голосов
/ 04 августа 2011

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

-(CGSize)contentSizeForViewInPopover
{
    return self.view.bounds.size;
}
11 голосов
/ 09 февраля 2011

У меня была похожая проблема.

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

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

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

Надеюсь, это полезно.

Kurt

9 голосов
/ 12 февраля 2014

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

- (void)viewDidLoad
{
    [super viewDidLoad];

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

UIViewController.contentSizeForViewInPopover устарел первым в iOS 7.

6 голосов
/ 19 октября 2010

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

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

Контроллеры Pushing View:

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

Отображение панели инструментов:

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

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

5 голосов
/ 14 июня 2012

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

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

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

4 голосов
/ 12 ноября 2010

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

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

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

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

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

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

2 голосов
/ 15 мая 2013

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

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

- (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");
}
2 голосов
/ 03 декабря 2012

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

self setContentSizeForViewInPopover:CGSizeMake(320, 500)];
...