Как динамически изменить размер содержимого UIPopoverController? - PullRequest
26 голосов
/ 15 декабря 2011

У меня есть UIViewController, который содержит UITableView. Это UIViewController отображается как UIPopoverController.

Теперь дело в том, что количество элементов в tableView не является постоянным, и я хочу, чтобы размер всплывающего окна (то есть - popoverContentSize) корректировался в соответствии с количеством элементов в tableView

Наивно, я думал, что если я установлю contentSizeForViewInPopover в viewDidLoad после того, как я загружу tableView со всеми предметами - это будет сделано.

Это не так.

Итак, если коротко, мой вопрос: как я могу изменить popoverContentSize непосредственно с contentViewController - после того, как он был представлен?

Приложение: enter image description here

Ответы [ 8 ]

47 голосов
/ 19 августа 2013

Я могу очень поздно ответить, но для нового пользователя из iOS 7 используйте следующую строку в вашем UIViewController i, e contentViewController вашего UIPopOverViewConotroller

-(void) viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    self.preferredContentSize=myTableView.contentSize;
}

Надеюсь, это поможет пользователю iOS 7.

9 голосов
/ 15 декабря 2011

Ну, в конце концов я сделал что-то, что я не уверен, что это правильно, но это работает.

Я добавил ссылку в моем contentViewController в popoverController:

@property (nonatomic , assign) UIPopoverController *popoverControllerContainer;

Затем я добавил код изменения размера для viewWillAppear и viewDidAppear:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView reloadData];
}

-(void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.contentSizeForViewInPopover = self.tableView.contentSize;
}

-(void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self.popoverControllerContainer setPopoverContentSize:self.contentSizeForViewInPopover animated:YES];
}

Так что хранить ссылку на поповер - это хакерство, так что я открыт, чтобы услышать лучшие идеи.

7 голосов
/ 16 ноября 2014

Для iOS 7 или выше.

- (CGSize)preferredContentSize {
    return CGSizeMake(320, 550);
}

Если вы являетесь дочерним элементом контейнера, перенаправьте размер контента на себя.Например, в подклассе UINavigationController:

- (CGSize)preferredContentSize {
    return self.topViewController.preferredContentSize;
}
7 голосов
/ 24 сентября 2012

A UIViewController класс имеет свойство

self.contentSizeForViewInPopover

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

И для расширенияВ решении я использовал метод rectForSection: , чтобы получить размер раздела (у меня есть только 1 раздел, поэтому его достаточно легко получить), а затем добавил высоту панели навигации (кажется, что20).поэтому я могу создать всплывающее окно размером с готовое представление таблицы:

CGRect sectionRect = [view.tableView rectForSection:0];

if (sectionRect.size.height + 20 < POPOVER_SIZE.height)
    view.contentSizeForViewInPopover = CGSizeMake(POPOVER_SIZE.width, sectionRect.size.height + 20);
else
    view.contentSizeForViewInPopover = POPOVER_SIZE;

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

1 голос
/ 10 марта 2016

Мое приложение имеет меню с подменю, которое создается из всплывающего окна и встроено в контроллер навигации, например, UINavigationController -> TopMenuViewController -> SubMenuViewController xN.

Ни одно из вышеперечисленных решений не помогло мне.

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

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationController.preferredContentSize  = CGSizeMake(450.0f, 0.0f);// increase standard width (320.0)
}


- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    self.navigationController.preferredContentSize = self.tableView.contentSize;
}
0 голосов
/ 11 мая 2016

Это должно сработать

override func viewWillLayoutSubviews() {
  super.viewWillLayoutSubviews()

  self.preferredContentSize = CGSizeMake(0, self.tableView.contentSize.height)}
0 голосов
/ 31 января 2016

iOS8 / 9 решение - просто переопределите preferredContentSize и принудительно верните представление таблицы в макет, прежде чем вернуть contentSize.

- (CGSize)preferredContentSize {
    [self.tableView layoutIfNeeded];
    return self.tableView.contentSize;
}
0 голосов
/ 24 октября 2013

У меня была такая же проблема, и ни один из найденных ответов не сработал. Я соединился, что, я думаю, работает хорошо.

В моем initWithCoder есть массив, содержащий мои значения. Я просто запускаю этот код:

- (id)initWithCoder:(NSCoder *)aDecoder
{
//Popover Choices

_importantChoices = [NSMutableArray array];
[_importantChoices addObject:@"Bakery"];
[_importantChoices addObject:@"Beverage Dry Mix"];
[_importantChoices addObject:@"Beverage RTD"];
[_importantChoices addObject:@"Crisps"];
[_importantChoices addObject:@"Meat"];
[_importantChoices addObject:@"Supplements"];


//Calculate size of Popover
self.clearsSelectionOnViewWillAppear = NO;
NSInteger rowsCount = [_importantChoices count];
NSInteger singleRowHeight = [self.tableView.delegate tableView:self.tableView
                                       heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
NSInteger totalRowsHeight = rowsCount * singleRowHeight;
CGFloat largestLabelWidth = 0;
for (NSString *tmp in _importantChoices) {
    CGSize labelSize = [tmp sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20.0f]}];
    if (labelSize.width > largestLabelWidth) {
        largestLabelWidth = labelSize.width;
    }
}
CGFloat popoverWidth = largestLabelWidth + 100;     //Add a little padding to the width
self.preferredContentSize = CGSizeMake(popoverWidth, totalRowsHeight);
return self;
}
...