自动布局和 UIPopoverController

Posted

技术标签:

【中文标题】自动布局和 UIPopoverController【英文标题】:Autolayout and UIPopoverController 【发布时间】:2015-03-18 17:02:44 【问题描述】:

我创建了一个面板,其中包含一些子视图,并使用NSLayoutConstraints 来实现定位。

然后我会将其显示在UIPopoverController 中。在设置它之前,我会调用[UIView layoutIfNeeded]命令来强制它自己调整大小(整体大小基于其中的图像大小,可以是不同的大小)。

PhotoDisplayPanel *panel = [[PhotoDisplayPanel alloc] initWithPhoto:cell.photo isAddPhoto:cell.isAddPhoto];

DLog(@"BEFORE | panel.frame: %@", panel);

[self.view addSubview:panel];

DLog(@"MIDDLE | panel.frame: %@", panel);

[panel layoutIfNeeded];

DLog(@"AFTER | panel.frame: %@", panel);

日志:

DEBUG | -[LoginViewController viewDidLoad] | BEFORE | panel.frame: <PhotoDisplayPanel: 0x7878a3f0; frame = (0 0; 0 0); layer = <CALayer: 0x7878a7e0>>
DEBUG | -[LoginViewController viewDidLoad] | MIDDLE | panel.frame: <PhotoDisplayPanel: 0x7878a3f0; frame = (0 0; 0 0); layer = <CALayer: 0x7878a7e0>>
DEBUG | -[LoginViewController viewDidLoad] | AFTER | panel.frame: <PhotoDisplayPanel: 0x7878a3f0; frame = (-358 -245; 578 289); layer = <CALayer: 0x7878a7e0>>

以前,我会在将 [panel layoutIfNeeded] 调用添加到视图之前添加它。这工作得很好。但是在 ios 8.1 中,他们改变了 layoutIfNeeded 的工作方式,如果你在将我的面板添加到视图之前调用它,它会吓坏并开始打破约束以使其正常工作。

我的问题是使用UIPopoverController,因为我不能调用layoutIfNeeded 我的面板没有大小,所以它使用弹出框的默认大小:

虽然面板看起来像:

我创建UIPopoverController,将面板设置为其视图,然后将preferedContentSize 属性设置为面板的大小:

UIViewController *viewController = [[UIViewController alloc] init];
viewController.view = self.currentPanel;
viewController.preferredContentSize = CGSizeMake(self.currentPanel.frame.size.width, self.currentPanel.frame.size.height + 00);

由于面板尚未调整大小,因此为 (0, 0)。

我现在的问题是,如何强制我的面板根据约束自行调整大小?

【问题讨论】:

【参考方案1】:

解决方案是根据您的约束条件计算 preferredContentSize。 注意:您的约束必须固定(左/上/右/下)到视图控制器视图,以便能够计算视图的总宽度/高度。

实现的方法,在你的 viewWillAppear 中添加这些行:

- (void)viewWillAppear:(BOOL)animated 
[super viewWillAppear:animated];

CGSize resultSize = [self.view systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
self.preferredContentSize = resultSize;

【讨论】:

这应该被标记为答案。我对其进行了测试,效果很好。【参考方案2】:

Tanguy G. 工作答案的 Swift 4/5 版:

override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)
    let resultSize = view.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
    self.preferredContentSize = resultSize

【讨论】:

以上是关于自动布局和 UIPopoverController的主要内容,如果未能解决你的问题,请参考以下文章

如何使 UIPopoverController 自动改变其箭头方向

按下外部时 UIPopoverController 不会自动关闭

使用 UIPopoverController 显示的 UIViewController 的 Size-Class 错误

MonoTouch 和 UIPopoverController

iOS 7 上的 UIPopoverController 和键盘导致奇怪的动画

有啥方法可以恢复 UIPopoverController 的 3D 效果和/或阴影?