美文网首页
iOS 13 UIPopoverPresentationCont

iOS 13 UIPopoverPresentationCont

作者: Just丶Go | 来源:发表于2019-09-26 14:22 被阅读0次

iOS 13中,UIPopoverPresentationController 中的箭头 arrowframe包含在了vc.view中。导致以前正常的布局在iOS 13上错误显示。

文后有补充约束的方式!!!

iOS 13截图

image.png
iOS 12截图
image.png

先贴一段测试代码,方便更好的理解

@implementation ViewController

- (void)showVC:(UIButton *)button
{
    PresentatedViewController *vc = [[PresentatedViewController alloc] init];

    vc.preferredContentSize = CGSizeMake(300, 300);
    vc.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController *pvc = vc.popoverPresentationController;
    pvc.permittedArrowDirections = UIPopoverArrowDirectionDown;
    pvc.sourceView = button;
    pvc.sourceRect = button.bounds;
    
    [self presentViewController:vc animated:YES completion:nil];
}

iOS 13上,仔细对比发现存在以下变化:

1. vc.preferredContentSize 设置的大小为 {300, 300}。但是当你设置箭头方向在左或在右时
'permittedArrowDirections = UIPopoverArrowDirectionLeft/ UIPopoverArrowDirectionRight',
你的`contentSize.width` 会增加13pt,变为{313, 300}。
同理方向为上或下时,`contentSize.height` 会增加13pt,变为{3, 313}。
2. 从`1`中看出,arrow包含在了vc中,并且vc会自动在响应的方向上增加13pt。从而造成添加在`vc.view`
上的视图被遮挡或者显示不完全的效果。

以上问题经笔者Google最终在twitter上有说明,这不是一个bug,而且苹果这次的一个特性,类似于UIViewControllersafeArea的特性。
最终经笔者查阅苹果开发文档与安全区域相关联的属性和多次尝试后找到最终解决的钥匙!!!


解决代码如下:

@implementation PresentatedViewController

- (void)loadView
{
    [super loadView];
    [self setupViews];
}

- (void)setupViews
{
    self.view.backgroundColor = [UIColor greenColor];
    self.bgView = [UIView new];
    self.bgView.backgroundColor = [UIColor yellowColor];

    [self.view addSubview:self.bgView];
}

- (void)viewWillLayoutSubviews
{
    // 关键点在这里, 这里获取到layoutFrame,使用这个值来布局,就会让出`arrow`所占用的位置。
    CGRect layoutFrame = self.view.safeAreaLayoutGuide.layoutFrame;
    
    self.bgView.frame = layoutFrame;
    
    CGRect frame = self.view.frame;
    self.bottomView.frame = CGRectMake(0, CGRectGetHeight(frame) - 30, CGRectGetWidth(frame), 30);
    [super viewWillLayoutSubviews];
}

@end

关键点就在 self.view.safeAreaLayoutGuide


以下是各方向的layoutFrame
pvc.permittedArrowDirections = UIPopoverArrowDirectionLeft

image.png
pvc.permittedArrowDirections = UIPopoverArrowDirectionRight
image.png

pvc.permittedArrowDirections = UIPopoverArrowDirectionDown

image.png
pvc.permittedArrowDirections = UIPopoverArrowDirectionUp
image.png

通过以上打印发现,若要排除arrow在外,只需要将容器的frame设置为self.view.safeAreaLayoutGuide.layoutFrame即可


***begin-补充-begin***

image.png
使用约束(Masonry)进行布局,就利用mas_safeAreaGuide相关属性即可.

    e.g.如前文的示例代码(上图)

    // way 1
    [self.bgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view.mas_safeAreaLayoutGuide);
    }];
    // way 2
    [self.bgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);
        make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
        make.leading.equalTo(self.view.mas_safeAreaLayoutGuideLeading);
        make.trailing.equalTo(self.view.mas_safeAreaLayoutGuideTrailing);
    }];

***end-补充-end***
OK~ 搞定

相关文章

网友评论

      本文标题:iOS 13 UIPopoverPresentationCont

      本文链接:https://www.haomeiwen.com/subject/kacoectx.html