我编写了代码,如果选择了 UICollectionView 单元格但由于某种原因不可用,则显示该单元格中的弹出窗口。它工作正常,只是内容从未正确定位在弹出气泡内。请注意,从显示的两个示例中,内容始终向插入符号移动大约插入符号厚度的一半。
很明显,尺寸计算正确,但似乎弹出控制器只是错误地计算了 popupView 的位置。由于移动的方向超出了我的控制范围,因此我不能将所有内容都移动几个像素作为解决方法。
故事板只有一个 popupView,其约束使其在场景视图中水平和垂直居中:
这是我的代码...请注意,我打开了视图周围的边框只是为了强调这种转变。
// Inside collectionView:didSelectItemAtIndexPath:
UIStoryboard* mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
MenuUnavailableViewController* muc = [mainStoryboard instantiateViewControllerWithIdentifier:@"MenuOptionUnavailable"];
muc.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:muc animated:NO completion:nil];
MenuCollectionViewCell* menuCell = (MenuCollectionViewCell*) [menuCollection cellForItemAtIndexPath:indexPath];
muc.popoverPresentationController.sourceView = menuCollection;
muc.popoverPresentationController.sourceRect = menuCell.frame;
muc.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
@implementation MenuUnavailableViewController
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.view layoutSubviews];
self.preferredContentSize = self.popupView.bounds.size;
self.popupView.layer.borderColor = [UIColor blackColor].CGColor;
self.popupView.layer.borderWidth = 2;
self.popupView.layer.cornerRadius = 12;
}
我已经使用这个公式成功地做了弹出窗口相当长一段时间了,然后有一天,一些 iOS 或 Xcode 更新悄悄地打破了定位(不确定,但我认为它是在 iOS 13 或 14 左右)。有人知道我做错了什么吗?我一直在寻找在最新 iOS 版本下实现弹出窗口的完整示例,但在任何地方都找不到。
不确定什么可能发生了变化,或者什么时候......而且,也许你的布局“很幸运”,所以你没有注意到它......但是......
我们要根据
控制器视图的大小设置
.preferredContentSize
- 而不是您的 popupView
子视图。
此外,我们要确保内容限制在安全区域。
所以,如果我像这样设置
MenuUnavailableViewController
:
带有“不可用”和“原因:”标签的内容拥抱和抗压缩优先级全部设置为
Required
...
Unavailable Lbl
标签将决定宽度在调用控制器中,设置标签的字符串属性。
然后,
MenuUnavailableViewController
类看起来像这样:
@implementation MenuUnavailableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.unavailableLbl.text = _unavailableString;
self.reasonLbl.text = _reasonString;
self.preferredContentSize = [self.view systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
}
@end
无需在
viewWillAppear
中执行任何操作。
这是它的样子(循环通过 3 组字符串):
如果我们清除颜色和边框:
并且,只是为了展示它适用于不同的“箭头”方向: