Code Block override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() let safeAreaInsets = self.view.safeAreaInsets }
My concern is that if I were using a UIView (called myView below), I could automatically apply it with this code block and never think of it again.
Code Block var constraints = [NSLayoutConstraint]() constraints.append(myView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor)) constraints.append(myView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor)) constraints.append(myView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)) constraints.append(myView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)) }
Is there an equivalent call when I'm doing that for a UIViewController?
Also, from all my reading online many posts have said to use trailing and leading rather than top and bottom. However self.view.safeAreaInsets appears to only have top and bottom.
Have you ever tried? There's no difficulties to set constraints between the safeArea edges of the main view and SKView.SKView appears to have no process to do that.
(code at the bottom)
Then you ARE using storyboard and instantiating GameViewController through storyboard.it's still there and Main storyboard filename is set to Main within info.plist.
I just wanted to clarify how you instantiate GameViewController.
(By the way, why do you insist on not using storyboard? It seems to be the harder way for you.)
Fortunately, if you add right constraints for myView properly, they work as expected whether you set them with code or in storyboard.
You can set safeAreaLayout even if myView is aSKView.Am only using myView as a UIView to set safeAreaLayout.
Code Block import UIKit import SpriteKit class GameViewController: UIViewController { //### Change the type of `myView` to `SKView`. public let myView : SKView = { let myView = SKView() //### Needed to make added constraints to work properly myView.translatesAutoresizingMaskIntoConstraints = false return myView }() private func addConstraints(){ var constraints = [NSLayoutConstraint]() //add constraints.append(myView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor)) constraints.append(myView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor)) constraints.append(myView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)) constraints.append(myView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)) //activate NSLayoutConstraint.activate(constraints) } override func viewDidLoad() { super.viewDidLoad() //### Change the type of `view` to `UIView` (in Main.storyboard) //if let view = self.view as! SKView? { view.addSubview(myView) //### Add constraints in `viewDidLoad()` addConstraints() //### You have no need to delay these settings //var scene : GameScene! //DispatchQueue.main.async { let scene = GameScene(size: myView.frame.size) // let scene = GameScene(size: CGSize(width: screenDims.widthPts - self.view.safeAreaInsets.left - self.view.safeAreaInsets.right, height: screenDims.heightPts-self.view.safeAreaInsets.top-self.view.safeAreaInsets.bottom)) //### Do not get screen metrics in `viewDidLoad()` // myGlobalVars.widthPoints = screenDims.widthPts - self.view.safeAreaInsets.left - self.view.safeAreaInsets.right // myGlobalVars.heightPoints = screenDims.heightPts - self.view.safeAreaInsets.top - self.view.safeAreaInsets.bottom #if DEBUG //print("SIZE \(screenDims.heightPts)") print("SIZE \(self.view.safeAreaInsets.top)") print("SIZE \(self.view.safeAreaInsets.bottom)") #endif scene.anchorPoint = CGPoint(x: 0.0, y: 0.0) scene.backgroundColor = .brown//.clear //### for debugging scene.scaleMode = .aspectFit //### Use `myView` instead of `view` to show the GameScene. myView.isHidden = false myView.presentScene(scene) //} myView.ignoresSiblingOrder = true myView.showsFPS = true myView.showsNodeCount = true myView.showsPhysics = true //} } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() #if DEBUG print ("GVC viewWillLayoutSubviews") #endif //### Remove these ↓ // let constraints = [ // view.centerXAnchor.constraint(equalTo: view.centerXAnchor), // view.centerYAnchor.constraint(equalTo: view.centerYAnchor), // view.widthAnchor.constraint(equalToConstant: 100), // view.heightAnchor.constraint(equalTo: view.widthAnchor)] // NSLayoutConstraint.activate(constraints) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() getScreenDimensions(screen: &screenDims) if myGlobalVars.safeSceneRect == .zero { //### Do not add constraints in `viewDidLayoutSubviews()` // addConstraints() // createConstraints(view: myView) myGlobalVars.sceneRect = view.frame } if #available(iOS 11.0, *) { myGlobalVars.topSafeArea = view.safeAreaInsets.top myGlobalVars.bottomSafeArea = view.safeAreaInsets.bottom } else { myGlobalVars.topSafeArea = topLayoutGuide.length myGlobalVars.bottomSafeArea = bottomLayoutGuide.length } //### Change only `size` of the `scene` if you need myView.scene?.size = myView.frame.size } override var shouldAutorotate: Bool { return false } override var supportedInterfaceOrientations: UIInterfaceOrientationMask { if UIDevice.current.userInterfaceIdiom == .phone { return .portraitUpsideDown } else { return .all } } override var prefersStatusBarHidden: Bool { #if DEBUG print ("GVC prefersStatusBarHidden") #endif return false } }
(Some lines kept there, to clarify which lines should be removed. Please read comments with ###.)