Search code examples
swiftxcodeorientationuiinterfaceorientation

App changes to different controller view when changing orientation


I'm developing an app using Xcode 9.2 and swift 4 and I needed to allow just one view in my app to change to landscape, so I added the code below to my AppDelegate

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    if globalVariables.gIsDosageView == "Y" {
        if UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight {
            return UIInterfaceOrientationMask.all;
        } else {
            return UIInterfaceOrientationMask.portrait;
        }
    } else {
        return UIInterfaceOrientationMask.portrait;
    }
}

The global variable is set to "N" on every other controller and so only DosageView has it set to "Y". In the DosageView controller I added this method to help with the transition.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    hideViews()
    if size.width < 400 {
        DispatchQueue.main.async() {
            self.userImg.isHidden = false
            self.burgerImg.isHidden = false
            self.deviceImg.isHidden = false
            self.portraitView.isHidden = false
            self.landscapeView.isHidden = true
        }
    }
    else {
        DispatchQueue.main.async() {
            self.userImg.isHidden = true
            self.burgerImg.isHidden = true
            self.deviceImg.isHidden = true
            self.portraitView.isHidden = true
            self.landscapeView.isHidden = false
            self.loadLandscapeView()
        }
    }
}

I've set up a LandscapeView and a PortraitView and the method above helps to toggle between them and it all works fine. If I move to the next view or return to the main screen and then return to the DosageView and then change the orientation to Landscape it works but if I go to the next view and then from there to the Connect view and connect (via BLE, NFC or QR) it then returns to the DosageView. When I change the orientation to Landscape it changes back to the Connect view. There is no direct link between these two views as you have to go through the Instruction view to get to Connect View for the DosageView, so how can this happen?

When I run it under debug and put a breakpoint in the ViewDidLoad on Connect View, it runs every time the DosageView changes to Landscape. If anyone can tell me what is going on I would be grateful as this is driving me crazy.


Solution

  • It was actually a colleague who sorted this for me and as he correctly pointed out it was a Lottie run call causing the problem. For anyone using Lottie and experiencing this problem, simply check your animation code. I had originally plagiarised code from a Splash screen as below

    splashAnimation!.loopAnimation = false
        splashAnimation!.play(fromProgress: 0,
                            toProgress: 1.0,
                            withCompletion: { (finished) in
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let controller = storyboard.instantiateViewController(withIdentifier: "Menu")
            self.present(controller, animated: true, completion: nil)
        })
    

    This code works fine as it moves on to the main screen on completion. However, the screen that was causing the problems moves between two different screens and to fix the problem, my colleague simply removed the withCompletion part as below

    splashAnimation!.loopAnimation = true
                splashAnimation!.play(fromProgress: 0,
                                      toProgress: 1.0)