The viewWillTransitionToSize method is invoked on device orientation. The problem is this is invoked on all the view controllers .
If view controller A initiates view controller B with push segue and then the device is rotated, the viewWillTransitionToSize method from A is also invoked. How to disable this?
You need to put in
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
handleLevelOrientation()
inside your viewWillTransitionToSize function. Here is my code:
override func viewWillTransitionToSize(
size: CGSize,
withTransitionCoordinator
coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
handleLevelOrientation()
}
Just like in viewDidLoad you need to put in a super, so that viewWillTransitionToSize function is not called from all of your view controllers.
Related
The new size classes based Autorotation is a pain if you want custom behavior. Here are my requirements and flow:
View Controller 1(VC1) modally presents View Controller 2 (VC2)
VC1 only supports landscape, portrait, or both depending on user settings (achieved via supportedInterfaceOrientations). For this example, we assume it is locked to landscape,
VC 2 supports both landscape & portrait
I use Size classes and in View Controller 1, I check for statusBarOrientation in viewWillTransition(to size...) to configure interface elements positioning & other customizations.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
let orientation = UIApplication.shared.statusBarOrientation
NSLog("View will transition to \(size), \(orientation.rawValue)")
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { [unowned self] (_) in
....
}
}
This works, except when VC 2 is presented and the device is rotated. VC 1 is all messed up when VC 2 is dismissed. To be sure, I would like to refresh layout of View Controller 1 when it appears. How do I do that? I tried UIViewController.attemptRotationToDeviceOrientation() but it doesn't force the autorotation methods to be called again.
EDIT: As can be seen, in VC1 I check for statusBarOrientation to determine interface orientation. That poses a problem, because statusBarOrientation gets changed to portrait when VC2 rotates to portrait mode. And viewWillTransition to size gets invoked on VC1 at the same time where I force layout to portrait mode.
I have tabBarController application with 4 viewcontrollers. This application is landscape orientation enabled so I have viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator in each viewcontroller.m file to control the orientation changes.
The problem I'm having, is when I change the device orientation while in the 3rd viewcontroller, the viewWillTransitionToSize in the 2nd viewcontroller is called so the wrong code is ran.
How is it possible that the 2nd viewcontroller's viewWillTransitionToSize is even called? Especially, when it hasn't even been loaded yet. I know it hasn't been loaded because I NSLog it's viewDidLoad and it shows when I change orientation from the 3rd viewcontroller.
Additional Info: There is no code in the 3rd viewcontroller's viewWillTransitionToSize, viewWillAppear, viewWillDisappear, etc. that would reference the 2nd viewcontroller.
I'm using Xcode 8.2.1 and Objective-C code. Please help, thanks.
Test to see which UIViewController is the selected UIViewController before handling the transition.
In Swift:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
{
guard self == tabBarController?.selectedViewController else { return }
// handle transition here
}
In my situation, the UIViewController was embedded in a UINavigationController so I had to handle it slightly differently:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
{
guard self.navigationController == tabBarController?.selectedViewController else { return }
// handle transition here
}
I replaced each instance of
viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator
with
willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
to avoid the aforementioned issue with viewWillTransitionToSize...
I want to detect the orientation change in different ViewControllers. I used this code
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
print("roration detected- ViewController 1")
}
It worked fine until I added this code in another ViewController. Now the function is executed only in the second ViewController. If I deleted from there than it start working in the first ViewController again. Do you have an idea what the problem is?
You should try to call super method:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
print("rotation detected- ViewController 1")
}
My application has Tabbar and Navigation options. My problem is, when device is rotating to landscape, previous viewcontroller viewwilltransitiontosize is also calling
Let's explain the scenario,
The first screen is AssignmentViewController
The second screen is SubmissionListViewController
Both class I have override viewwilltransitiontosize method. when I rotate to landscape in the 2nd view controller time, it first calls AssignmentViewController's viewwilltransitiontosize method then it calls SubmissionListViewController's viewwilltransitiontosize
here is my piece of code
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
if UIDevice.currentDevice().orientation.isLandscape.boolValue {
print("Landscape")
self.navigationController?.setNavigationBarHidden(true, animated: false)
self.landscapeVideo()
self.tabBarController!.tabBar.hidden = true
} else {
print("Portrait")
self.navigationController?.setNavigationBarHidden(false, animated: false)
self.videoinPortraitMode()
self.tabBarController!.tabBar.hidden = false
}
}
any idea or help please?
I have a view controller that i want to animate my views position when orientation changes.
i have some views set in storyboard and some added in the ViewControllers viewDidLoad.
I'm overriding
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
coordinator.animateAlongsideTransition({context in
self.myView.frame = CGRectMake(0,0,200,200);
}, completion: nil)
}
the size changes but not in an animation.
I also have a button that is set in storyboard with autolayout.
And it also moves according to its constraints but the change is not animated.
Am i missing something?