将元素定位到具有安全区域的 CGRect

Posted

技术标签:

【中文标题】将元素定位到具有安全区域的 CGRect【英文标题】:Position element to CGRect with Safe Area 【发布时间】:2018-02-23 13:36:28 【问题描述】:

我正在声明一个按钮:

let button = UIButton(frame: CGRect(x: ?, y: ?, width: 50, height: 50))

但我注意到如何设置 xy 相对于安全区域,以便它在 >= ios 11<= iOS 10 上都能正常工作。

我尝试使用self.view.safeAreaInsets,但由于某种原因它返回 0.0。任何想法如何解决这个问题?

【问题讨论】:

首先,如果可能,您应该使用自动布局。把这段代码放在哪个地方,也许是太早了?在其他地方试试 viewDidLayoutSubviews 我在 viewDidAppear 中设置按钮 我想知道 - 因为您 使用自动布局 - 您会遇到@Adis 提供的答案的问题。一个例子....假设viewDidAppear 纵向执行。你会得到一个考虑了缺口的“Y”值,但你的“X”值不会。现在,逆时针旋转,或将槽口向左移动。我很确定你的按钮会被凹口遮住。在编写更多代码之前进行测试可能是个好主意。 @dfd,我的应用只是肖像,还会有问题吗? 可能不会,但请记住“缺口”。纵向只意味着它也可以在底部。 【参考方案1】:

如果您使用自动布局和约束,这会容易得多,但您可以通过这种方式获得安全区域的边距:

if #available(iOS 11.0, *) 
    if let window = UIApplication.shared.keyWindow 
        let topMargin =  window.safeAreaInsets.top
        let leftMargin =  window.safeAreaInsets.left
    

【讨论】:

【参考方案2】:

我在制作动画时也有同样的问题。

终于解决了问题,idea:create a frame等于safeArea frame。

(设备方向仅限左和右)

CGRect safeAreaFrame;

if (@available(iOS 11.0, *)) 
    UIEdgeInsets safeAreaInsets = self.view.safeAreaInsets;
    safeAreaFrame = CGRectMake(safeAreaInsets.left,
                               safeAreaInsets.top,
                               self.view.frame.size.width - safeAreaInsets.left - safeAreaInsets.right,
                               self.view.frame.size.height - safeAreaInsets.top - safeAreaInsets.bottom);
 else 

    safeAreaFrame = self.view.frame;

那么你就可以使用安全区域框架了,例如:

UIView *view = [[UIView alloc] initWithFrame:safeAreaFrame];
view.backgroundColor = UIColor.redColor;
[self.view addSubview:view];

注意:viewDidLoad 中的安全区域插入返回 (0, 0, 0, 0), 因此它们的设置晚于 viewDidLoad, 放入 viewSafeAreaInsetsDidChange 或 viewDidAppear。 我希望这会对你有所帮助。

【讨论】:

【参考方案3】:

对于 iOS 11:

如果您在viewDidLoad, viewWillAppear, etc 上调用self.view.safeAreaInsets,它将为零

如果您在viewDidLayoutSubviews, viewDidAppear 上调用它,它应该具有值

【讨论】:

以上是关于将元素定位到具有安全区域的 CGRect的主要内容,如果未能解决你的问题,请参考以下文章

定位导航栏顶部的安全区域

WebDriver API 元素定位

Appium元素定位难点:混合式的native+webview

Webkit - 修复定位元素似乎具有固有的堆叠上下文

同时具有两种定位的元素

使用原生js的scrollTop,刷新进入页面定位到某一个dom元素