iOS - Wrong UIScreen bounds in viewWillTransition for iPad
Asked Answered
P

1

5

I have to check if my device has changed orientation in iOS 8+.

My approach is:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    let isLand = UIScreen.main.bounds.width > UIScreen.main.bounds.height

    coordinator.animate(alongsideTransition: nil) { _ in
        let isLand2 = UIScreen.main.bounds.width > UIScreen.main.bounds.height


        print("\(isLand) -> \(isLand2)")
    }
}

it works fine in iPhone but in iPad isLand has already the new value which should be after the orientation completion, so:

Portrait > Landscape: true -> true

Landscape > Portrait: false -> false

According to the documentation the bounds should change with the orientation so it should have a before/after bounds, shouldn't it?

UIScreen main bounds:

This rectangle is specified in the current coordinate space, which takes into account any interface rotations in effect for the device. Therefore, the value of this property may change when the device rotates between portrait and landscape orientations.

Whereas it works fine both iPhone and iPad if I use the bounds of the current root view controller like this:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    let isLand = UIApplication.shared.keyWindow!.rootViewController!.view.bounds.width > UIApplication.shared.keyWindow!.rootViewController!.view.bounds.height

    coordinator.animate(alongsideTransition: nil) { _ in
        let isLand2 = UIApplication.shared.keyWindow!.rootViewController!.view.bounds.width > UIApplication.shared.keyWindow!.rootViewController!.view.bounds.height


        print("\(isLand) -> \(isLand2)")
    }
}

Portrait > Landscape: false -> true

Landscape > Portrait: true -> false

Poised answered 14/3, 2017 at 9:49 Comment(1)
Is The viewWillTransition() method called before or after viewDidAppear?Aruabea
D
8

You should try using the containerView of the coordinator context instead.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    let isLand = coordinator.containerView.bounds.width > coordinator.containerView.bounds.height

    coordinator.animate(alongsideTransition: nil) { _ in
        let isLand2 = coordinator.containerView.bounds.width > coordinator.containerView.bounds.height

        print("\(isLand) -> \(isLand2)")
    }

}

If you want to get further information regarding the transition you can use the func view(forKey: UITransitionContextViewKey) and func viewController(forKey: UITransitionContextViewControllerKey) using the .from key.

Duenas answered 14/3, 2017 at 14:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.