Safe Area changes in parent VC when presenting modally VC in landscape
Asked Answered
S

1

13

Safe Area Insets in first UIViewController changes to Safe Area Inset for landscape when I present SecondViewController, which supports only landscape orientation.

GIF with described bug

GIF with described bug that touches TabBar and TableView

FirstViewController:

class ViewController: UIViewController {

  @IBAction func showSecondVC(_ sender: Any) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let controller = storyboard.instantiateViewController(withIdentifier: "SecondViewController")

    self.present(controller, animated: true, completion: {
      print("completed")
    })
  }

  override func viewSafeAreaInsetsDidChange() {
    print(view.safeAreaInsets)
    super.viewSafeAreaInsetsDidChange()
    print(view.safeAreaInsets)
  }
}

Second ViewController:

class SecondViewController: UIViewController {
  override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return [.landscape]
  }

  @IBAction func dismissYourSelff(_ sender: Any) {
    self.dismiss(animated: true, completion: nil)
  }
}

Console output:

UIEdgeInsets(top: 44.0, left: 0.0, bottom: 34.0, right: 0.0)
UIEdgeInsets(top: 44.0, left: 0.0, bottom: 34.0, right: 0.0)
UIEdgeInsets(top: 0.0, left: 44.0, bottom: 21.0, right: 44.0)
UIEdgeInsets(top: 0.0, left: 44.0, bottom: 21.0, right: 44.0)
completed
Superpose answered 10/11, 2017 at 13:17 Comment(2)
Did you find a solution yet?Paunchy
@Paunchy check my answer below. I fixed it with showing a snapshot during presentation and removing it afterwards. Only for iPhone X devices.Superpose
S
2

That's how I solved the problem with constraints: https://gist.github.com/filletofish/b56600e9e661aa6e49cc0a56a98b37a3

I had to use snapshots to prevent wrong layout of TabBar and TableView.

override func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
    var completionToRemoveSnapshot: (() -> ())? = nil

    let shouldUseSnapshot = SDiOSVersion.deviceSize() == .Screen5Dot8inch &&
      viewControllerToPresent.supportedInterfaceOrientations == .landscape

    if shouldUseSnapshot {
      if let snapShot = self.view.snapshotView(afterScreenUpdates: true) {
        viewController.view.addSubview(snapShot)
        completionToRemoveSnapshot = { snapShot.removeFromSuperview() }
      }
    }

    super.present(viewControllerToPresent, animated: flag, completion: {
      completionToRemoveSnapshot?()
      completion?()
    })
  }
Superpose answered 18/11, 2017 at 15:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.