【问题标题】:How To Dynamically change the contentSize of UIPopoverController?如何动态改变 UIPopoverController 的 contentSize?
【发布时间】:2023-03-15 20:58:01
【问题描述】:

我有一个包含UITableViewUIViewController。 这个UIViewController 显示在UIPopoverController 中。

现在,事情是tableView中的项目数不是恒定的,我希望弹出框的大小(即-popoverContentSize),根据项目数调整tableView

天真地,我在想如果我在将所有项目加载到 tableView 之后将 contentSizeForViewInPopover 设置为 viewDidLoad - 它会做到的。

没有。

所以简而言之,我的问题是:我怎样才能直接从contentViewController 更改popoverContentSize - 在它被呈现之后?

附录:

【问题讨论】:

    标签: objective-c ios cocoa-touch ipad uipopovercontroller


    【解决方案1】:

    嗯,最后我做了一些我不确定是否正确的事情,但它正在工作。

    我在 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];
    }
    

    所以,保留对弹出框的引用有点像 hack-ish,所以我愿意听取更好的想法。

    【讨论】:

    • 我使用相同的机制。我将方法createPopover 添加到用作弹出内容的 UIViewControllers 中。这些方法从self 创建一个弹出框,然后保存弹出框实例以供进一步访问。
    • 你好@Avraham 你的答案是我用过的那个,效果很好。我对您的解决方案有一个疑问:为什么您在将出现的方法中设置了视图的内容大小,而在确实出现了弹出框大小?为什么不能只用这两种方法中的一种来完成,因为我试过了,但是没有用?
    【解决方案2】:

    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;
    

    多个部分可能会更难,我没有尝试过。应该只是能够总结部分高度,但可能存在一些我不知道的间距问题。

    【讨论】:

    • 已弃用,请使用 iOS7 及更高版本的“preferredContentSize”。
    【解决方案3】:

    我可能会很晚才回答,但对于 iOS 7 的新用户 请在您的 UIViewController 中使用以下行,即 UIPopOverViewConotroller

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

    希望这对 iOS 7 用户有所帮助。

    【讨论】:

    • 这在 ViewWillAppear 中可能效果更好,因为它发生在视图出现之前。
    • 如果您在 popover 中使用 navigationController 并且即使设置了preferredContentSize 也会出现问题。尝试 [self.parentPopOverController setPopoverContentSize:CGSizeMake(250, 400) animated:YES];在推送 UIViewController 之前
    • 接受您的回答,因为它更新了。谢谢!
    • 您可能还需要 [myTableView sizeToFit];如果表有默认大小。这也应该放在 viewWillAppear 而不是 viewDidAppear 方法中。
    • 在 iOS 8 上,这必须进入 viewDidAppear,因为当调用 viewWillAppear 时 self.tableView 尚未正确布局,即它的高度为零。
    【解决方案4】:

    我遇到了同样的问题,但我找到的答案都没有。我拼凑起来,我认为效果很好。

    我的 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;
    }
    

    【讨论】:

      【解决方案5】:

      适用于 iOS 7 或更高版本。

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

      如果您是容器的子项,请将内容大小重新定向到您自己。例如。在UINavigationController 子类中:

      - (CGSize)preferredContentSize {
          return self.topViewController.preferredContentSize;
      }
      

      【讨论】:

      • 只是给尝试罗伯特方法的其他人的注释。它非常干净,适用于这个问题。但是,如果您在 UINavigationController 中显示 UITableView,它可能对您不起作用。 Avinash 似乎在这种情况下有效。
      • @DenVog - 好地方。我仍然希望继承UINavigationController 以从它的topViewController 中获取其首选状态栏。通常,我发现声明所需内容的方法比设置值更好,因为它可以防止 2 个不同的类可以用不同的值践踏同一属性的错误,这可能会导致不同的结果,具体取决于您执行操作的顺序。这与在 iOS 7 中创建 preferredStatusBarStyle 的原因类似。
      • 这是唯一对我有用的解决方案。设置 self.preferredContentSize 无效。
      【解决方案6】:

      iOS8/9 解决方案 - 只需覆盖 preferredContentSize 并在返回 contentSize 之前强制表格视图进行布局。

      - (CGSize)preferredContentSize {
          [self.tableView layoutIfNeeded];
          return self.tableView.contentSize;
      }
      

      【讨论】:

      • 如果嵌入到 UINavigationController 层次结构中,这会扩大视图,但不会缩小它。
      【解决方案7】:

      我的应用有一个菜单,其中包含源自弹出框并嵌入导航控制器中的子菜单,例如 UINavigationController -> TopMenuViewController -> SubMenuViewControllerxN。

      以上解决方案都不适合我。

      我的解决方案:在我的根菜单视图控制器类中,所有其他菜单视图控制器都从该类继承,添加以下代码:

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

      【讨论】:

        【解决方案8】:

        这应该可以解决问题

        override func viewWillLayoutSubviews() {
          super.viewWillLayoutSubviews()
        
          self.preferredContentSize = CGSizeMake(0, self.tableView.contentSize.height)}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多