IOS viewwilltransitiontosize method call all viewcontroller when rotate - ios

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?

Related

Programatically show the slide over master view in a UISplitViewController

When using a UISplitViewController in portrait mode on an iPad I am given a fullscreen view of my detail view controller which is intended. I can slide from the left and reveal the master view slide over, how can I trigger this slide over programmatically?
There's no easy way to do this it seems, but I have found that using the following code has the intended behaviour:
UIView.animate(withDuration: 0.2, animations: {
self.splitViewController?.preferredDisplayMode = .primaryOverlay
})
Make sure you set the display mode back to automatic on landscape rotation so that it will always show the master and detail like default:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { _ in
if UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight {
self.splitViewController?.preferredDisplayMode = .automatic
}
}, completion: nil)
}

animating views when orientation changes not working

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?

UINavigationController doesn't rotate when presenting child view controller

Here is my sample project
I have two view controllers embedded in a UINavigationController. On the first one, there is just a button performing a segue on the 2nd view controller. On the latter, a button dismiss it back to the 1rst view controller.
The 1rst view controller is not allowed to rotate and stays in Portrait while the 2nd is allowed to rotate in Landscape.
To do so, I added this code in the 1rst view controller:
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
}
and added an extension to UINavigationController:
extension UINavigationController {
override public func shouldAutorotate() -> Bool {
if let topViewController = topViewController {
return topViewController.shouldAutorotate()
}
return false
}
override public func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if let topViewController = self.topViewController {
return topViewController.supportedInterfaceOrientations()
}
return .Portrait
}
}
On the 2nd view controller, I add programmatically a label with some autolayout constraints. The label's title show the UIDevice.currentDevice().orientation.
My problem is the following:
When I put the device on landscape when I'm on the 1rst view controller, it's fine, the layout is laid for Portrait but when I tapp the button to present the 2nd view controller, this one stays on Portrait instead of switching to Landscape.
And bigger problem for me as in my real project I set some constraints depending on the device orientation, the UIDevice.currentDevice().orientation return the Landscape position.
What's wrong? Is it a normal behaviour? How can I fix it?
In your sample project, you're not updating the label when the device is rotated. You should override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) Also, Apple recommends that you not use UIDevice orientation but rather just look at the bounds of your view controller's view. For example:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
if size.height<size.width {
label.text = "Landscape"
} else {
label.text = "Portrait"
}
}
Calling UIViewController.attemptRotationToDeviceOrientation() in the viewWillAppear of the 2nd view controller did the trick.

showAnnotations when rotation changes

I have a SplitViewController with a mapview on as the detailViewController.
I add multiple annotations to the mapview. After adding them I call the showAnnotations:animated: method to zoom in/out the map so that all the annotations are shown in the visible portion of the map.
mapView.showAnnotations(mapView.annotations, animated: true)
Now I need the map to refocus itself when the orientation changes because the mapview's visible area reduces when you turn the iPad to portrait. So I call the same showAnnotations:animated: method in viewWillTransitionToSize:withTransitionCoordinator: method which fires when the orientation changes. But it doesn't work as expected.
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
mapView.showAnnotations(mapView.annotations, animated: true)
}
How do I make it refocus when orientation changes?
Demo project
Calling the showAnnotations within the viewDidLayoutSubviews method works perfectly.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
mapView.showAnnotations(mapView.annotations, animated: true)
}

viewWillTransitionToSize is invoked on all the view controllers

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.

Resources