在 iPhone X 中叠加时,UIView 的顶部位置不正确

Posted

技术标签:

【中文标题】在 iPhone X 中叠加时,UIView 的顶部位置不正确【英文标题】:Top of UIView isn't positioned well when overlayed in iPhone X 【发布时间】:2019-01-10 10:22:10 【问题描述】:

当在viewController 上按下按钮时,我目前正在覆盖UIView。我把它放在其他屏幕设备上,当我在iPhone X + 设备上运行时。它的定位不好。为了使其定位良好,我需要在其当前的top safeAreaInsets 中减去 40 个点。最初的20分是为了应付状态栏。当我这样做时,它可以工作,然后它就不能在其他没有缺口的 iPhone 上工作。我在这里做错了什么。这是我的代码

func contentFrame(extraTopOffset pOffset: CGFloat = 0) -> CGRect 
        var theFrame = self.view.bounds
        if let navBar = self.navigationBar 
            let topOffset = navBar.frame.origin.y + navBar.frame.size.height
            theFrame.size.height -= topOffset
            theFrame.origin.y += topOffset
        
        if #available(ios 11.0, *) 
            let safeInsets = UIApplication.shared.delegate!.window!?.safeAreaInsets
            let topOffset = safeInsets!.top - (20 + pOffset)
            theFrame.origin.y += topOffset
            theFrame.size.height -= topOffset + safeInsets!.bottom
        
        return theFrame
    

我在另一个 viewController 中显示覆盖的地方,我覆盖了该方法

override func showOverlay() 
        self.overlayView.frame = self.contentFrame()
        self.view.addSubview(self.overlayView)
    

【问题讨论】:

使用self.view.safeAreaInsets 代替UIApplication.shared.delegate!.window!?.safeAreaInsets 会有什么不同吗? @D.Mika 它没有 是否可以使用AutoLayout约束而不是直接设置框架? 【参考方案1】:

我通过使用我的实现来修复它。我检查当前设备是否有缺口,如果有,我从中减去 20。然后在我调用方法的时候加20分

class var hasNotch: Bool 
        if #available(iOS 11.0, *) 
            return (self.shared.delegate!.window!!.safeAreaInsets.top > 20)
        
        return false 
    

func contentFrame(extraTopOffset pOffset: CGFloat = 0) -> CGRect 
        var theFrame = self.view.bounds
        if let navBar = self.navigationBar 
            let topOffset = navBar.frame.origin.y + navBar.frame.size.height
            theFrame.size.height -= topOffset
            theFrame.origin.y += topOffset
        
        if #available(iOS 11.0, *) 
            let safeInsets = UIApplication.shared.delegate!.window!?.safeAreaInsets
            var extraOffset = safeInsets!.top - 20
            if UIApplication.yb_hasNotch 
                extraOffset -= pOffset
            
            theFrame.origin.y += extraOffset
            theFrame.size.height -= extraOffset + safeInsets!.bottom
        
        return theFrame
    

【讨论】:

【参考方案2】:

您可以使用这样的扩展程序。

extension UIDevice 
        var hasNotch: Bool 
            if #available(iOS 11.0, *) 
                let bottom = UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0
                return bottom > 0
             else 
                return false
            
        
    

【讨论】:

以上是关于在 iPhone X 中叠加时,UIView 的顶部位置不正确的主要内容,如果未能解决你的问题,请参考以下文章

iPhone X 上 SceneKit + SpriteKit 叠加的像素格式错误

有没有办法可以在 iPhone SDK 上制作叠加视图?

使用 iPhone X 的安全区域指南计算 UIView 的高度

iPhone/iPad 上的视频控制叠加

iPhone X 的 UIView 高度没有扩展

当 UIView 框架改变其大小时执行方法 iPhone iPad