4
\$\begingroup\$

will you please give your thoughts (code review) on these two way of solving orientation.

About the app:

We have a universal App. The main purpose of the app is to watch the videos. The app has four screens.

  1. Shows the list of shows
  2. show the list of episodes in the show
  3. details of an episode
  4. Player screen

The way we implemented is

  • a navigationalViewController that shows the viewController 1 (list of show)
  • then drill into viewController 2 (episodes of a show)
  • then drill into viewController 3 (episode details)
  • then viewController 4 ( with av media player view) presented modally from viewController 3

Requirement of orientation:

+--------+------------------+---------------------+-----------------------+-----------------------------+
| Device | Shows list (vc1) | Episodes list (vc2) | Episode details (vc3) | Player ViewController (vc4) |
+--------+------------------+---------------------+-----------------------+-----------------------------+
| iPad   | Landscape        | Landscape           | Landscape             | Landscape                   |
+--------+------------------+---------------------+-----------------------+-----------------------------+
| iPhone | Portrait         | Portrait            | Portrait              | Portrait & Landscape        |
+--------+------------------+---------------------+-----------------------+-----------------------------+

Method 1:

Implement this following code at app delegate level

func application(_ application: UIApplication, 
                 supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {

    guard let viewController = self.window?.rootViewController?.presentedViewController else {
        if UIDevice.current.userInterfaceIdiom == .pad {
            return .landscape
        }
        return [.portrait, .portraitUpsideDown]
    }

    if viewController is PlayerViewController && viewController.isBeingDismissed == false {
        return .all    
    } else {
        if UIDevice.current.userInterfaceIdiom == .pad {
            return .landscape
        }
        return [.portrait, .portraitUpsideDown]
    }
}

Method 2:

Implement this following code at navigationViewController level

class MyNavigaitonViewController: UINavigationController {

override var shouldAutorotate: Bool {
    if self.traitCollection.userInterfaceIdiom == .pad {
        return true // we are supporting both landscapeLeft and landscapeRight on iPad.
    }
    return false }

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    if self.traitCollection.userInterfaceIdiom == .pad {
        return .landscape // we are supporting both landscapeLeft and landscapeRight on iPad.
    }
    return .portrait } 

}

Player view controller has this following code in both Method 1 and Method 2

extension PlayerViewController {
override var shouldAutorotate: Bool {
    if self.traitCollection.userInterfaceIdiom == .pad {
        return true // we are supporting both landscapeLeft and landscapeRight on iPad.
    }
    // TODO: workout a way to support landscapeleft & right in phone
    return true
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.all
}
}
\$\endgroup\$
1
  • \$\begingroup\$ What use of viewController.isBeingDismissed == false condition? \$\endgroup\$
    – kelin
    Dec 1, 2017 at 9:43

2 Answers 2

1
\$\begingroup\$

What about implementing CoreViewController class which by default support landscape for iPad and portrait for iPhone. All your VCs inherit from it. As a result VC1,VC2 and VC3 will have it by default and in VC4 override rotation methods to add support for landscape mode?

\$\endgroup\$
1
\$\begingroup\$

I recommend to use default Apple-provided ways to implement this logic. You can use the delegate method to force your UINavigationController to use it's visibleViewController to determine the orientation. The visibleViewController is a wonderful property which will return modal vc if it's presented or top vc otherwise.

func navigationControllerSupportedInterfaceOrientations(_ navigationController: UINavigationController) -> UIInterfaceOrientationMask {
    return navigationController.visibleViewController?.supportedInterfaceOrientations ?? .all
}

Then override supportedInterfaceOrientations of all view controllers. This will be most flexible and portable solution.

If you want all-in-one-place solution you should use something like your Method 1.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.