SpriteKit 中的 safeAreaInsets 问题

Posted

技术标签:

【中文标题】SpriteKit 中的 safeAreaInsets 问题【英文标题】:safeAreaInsets issues in SpriteKit 【发布时间】:2018-02-23 07:48:16 【问题描述】:

我正在开发一款游戏,现在我注意到它在 iPhone X 上看起来不像我预期的那样。我需要在top right corner 上放置一个标签,而在 iPhone X 上该标签根本没有显示。所以我读到了Safe Area 并想出了这个解决方案:

游戏视图控制器:

override func viewDidLoad() 
    super.viewDidLoad()

    self.view.setNeedsLayout()
    self.view.layoutIfNeeded()
    self.view.layoutSubviews()


override func viewDidLayoutSubviews() 
    print("viewDidLayoutSubviews")
    print(self.view.safeAreaInsets.top)
    print(self.view.safeAreaInsets.bottom)


override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)

    let scene = GameScene(size: view.bounds.size)
    let skView = view as! SKView
    skView.showsFPS = false
    skView.showsNodeCount = false
    scene.scaleMode = .resizeFill
    skView.presentScene(scene)

在我的 GameScene 中,当用户这样做时,我会这样做

override func didMove(to view: SKView) 
    var label = SKLabelNode()
    if let safeAreaInsets = self.view?.safeAreaInsets 
        var y: CGFloat = 0.0
        if safeAreaInsets.top == 0.0  iPhone SE, 6/7/8, Plus
            y = self.frame.height - 10
         else  // iPhone X
            y = frame.maxY - safeAreaInsets.top - 5
        
        label.position = CGPoint(x: self.frame.width -100, y: y)
    

    label.text = "Highscore: 0"
    label.zPosition = 5

关于这个的两个问题:

1:

这可行,但我是否真的需要检查safeAreaInsets.top == 0.0 来检测我是否需要为 iPhone X 使用safeAreaInsets?两部手机的安全区域不应该一样吗?

2: 为了能够获得safeAreaInsets,我需要致电self.view.setNeedsLayout(), self.view.layoutIfNeeded(), self.view.layoutSubviews()(可能不是全部,而是其中一些)。如果我不使用这个,safeAreaInsets 总是 0.0。这是为什么呢?

【问题讨论】:

【参考方案1】:

你可以使用:

if #available(ios 11.0, *) 
    if let window = UIApplication.shared.keyWindow 
        let safeAreaBottom = window.safeAreaInsets.bottom
        let safeAreaLeft = window.safeAreaInsets.left
        let safeAreaRight = window.safeAreaInsets.right
        let safeAreaTop = window.safeAreaInsets.top
    

【讨论】:

【参考方案2】:
   private func safeAreaInsets() -> UIEdgeInsets 
        if #available(iOS 11.0, *) 
            return UIApplication.shared.windows.first?.safeAreaInsets ?? .zero
         else 
            return .zero
        
    

【讨论】:

以上是关于SpriteKit 中的 safeAreaInsets 问题的主要内容,如果未能解决你的问题,请参考以下文章

SpriteKit 中的循环背景音乐

touchesMoved中的SpriteKit + AVAudioPlayer:杀死fps

是否可以围绕 SpriteKit 中的任意点旋转节点?

等效于 SpriteKit 中的弹出框

基于 SpriteKit 中的碰撞检测更新分数的问题

touchesEnded:withEvent: 未检测到 SpriteKit 中的顶部节点