I have two "pages" in my app. one which should rotate between the 2 landscape modes but not allow portrait mode and the other which should rotate between the 2 portrait modes but not allow landscape mode.
How can one set this up so that the orientations are limited correctly when segueing between the two views?
I will write my own segue if I were you and set the orientation of the destination view in the perform method of your custom UIStoryboardSegue and will also set the orientation i want to allow in the shouldAutorotateToInterfaceOrientationof the destination view controller. You can have a look to this question related to custom segue I asked some time ago to get an idea of how to implement custom segue.
Related
I need to change my existent view in landscape to something similar like Youtube does in landscape .. Currently i'm using size classes and storyboard to achieve it but the problem is my layout should change considerably in landscape compared to the portrait and since the size classes for both ipad portrait and landscape is same ,should i use a separate view controller for the landscape version .. My current portrait view is also slightly complex which has child view controllers embedded in it .. What is the best approach to follow for the seamless transition from ipad portrait to landscape ..Do you think youtube is using different viewcontrollers/xib's to achieve it .. Another problem is this code has been written by some other company and the instructions given to me is to not change the existent code much .. I dont want to fiddle with it much ..
PFA for the images of how the current version looks and how it should look like landscape..
Current version
Proposed version
Edit 1: I have already implemented viewWillTransitionToSize in my view controller .. My question is, should i be using two different xib's or can i use a different view controller altogether for landscape version ..What are the pros and cons of it ? As evident from the below pics , i need to do quite a few changes to my landscape version ..
reduce the size of video , hide the segmented control and add two tableviews to the side..
You should implement the UIContentContainer protocol method viewWillTransitionToSize and check the width and/or height of size with your view controller's view's frame and act accordingly.
In Swift:
override func viewWillTransitionToSize(size: CGSize,
withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
if traitCollection.verticalSizeClass == .Regular && traitCollection.horizontalSizeClass == .Regular {
if size.width > self.view.frame.size.width {
// Moving to landscape
} else {
// Moving to portrait
}
}
}
Discussion
UIKit calls this method before changing the size of a
presented view controller’s view. You can override this method in your
own objects and use it to perform additional tasks related to the size
change. For example, a container view controller might use this method
to override the traits of its embedded child view controllers. Use the
provided coordinator object to animate any changes you make.
If you override this method in your custom view controllers, always
call super at some point in your implementation so that UIKit can
forward the size change message appropriately. View controllers
forward the size change message to their views and child view
controllers. Presentation controllers forward the size change to their
presented view controller.
I need to know if there is a way to tell a iOS7 device to set a views orientation without the device being rotated. Some way in code to trigger the device to calling the code that tells it which way to display the view.
If the device is in landscape and remains held in landscape orientation while a certain change happens I want to force a change to show the view in portrait orientation, at which point the user would need to turn the device to look at it properly. I'll explain why below
Looking at my app might make my description clearer - it is free to download
I have a number of view controllers (embedded in navigationControllers) and only one of them needs to be rotated into landscape and then only under certain conditions.
Solutions here on StackOverflow seem to be to make a category on UINavigationController giving it shouldAutorotate and supportedInterfaceOrientations methods and then use those methods in the individual viewControllers to block or allow rotations.
This has worked for me .... however
On the one view controller I wish to rotate , I don't want it to rotate all the time.
This view controller is the diveSiteDetailsController, (if you have downloaded the app you need to select dive sites on the first page then click the '+' to see it). It has a UISegmentedController and 4 subviews (3 tableviews and 1 other UIView). The current version on the App Store works fine now i've solved this - but looking at it may help you understand my issue better).
On diveSiteDetailViewController the UISegmentedController is used to switch between the 4 subviews.
All the subviews are used to enter data about the same dive site but as there is a lot of potential data, I have broken it into logical chucks each of which is a subview - location, data (depths,currents, visibility), type of environment and notes.
The .hidden property of each subview is used to make them appear and disappear.
I only want the second subview to rotate (the data view - it has some sliders on it that are easier to work with if in landscape).
restricting this rotation is easy - iI achieved it like this
- (NSUInteger)supportedInterfaceOrientations{
if (self.dsDataRangeSlidingTV.hidden) {
return UIInterfaceOrientationMaskPortrait;
}
return UIInterfaceOrientationMaskAllButUpsideDown;
}
Now the view will only rotate to landscape when the data table view is displayed.
However, once in landscape, if I chose a different subview with the UISegmentedController then they are, obviously, shown in landscape also as the iOS device hasn't done a rotation. This is the situation I am trying to avoid.
Rotating the iOS device will return those views to portrait as expected but i need to trigger the device to to reevaluate its display when I use the UISegmentedController to switch from the data subview to another subview and its that triggering that I don't know how to do.
any suggestions greatly received.
Heres a workaround that is working for me
I've added the following few lines to the end of my method that responds to the UISegmentedControl being tapped.
UIViewController *aDummyController = [[UIViewController alloc]init];
[self presentViewController:aDummyController animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];
adding a new viewController and popping it off triggers the rotation . This is a kludgey way of achieving what I wanted.
I found the solution in this post
Is there a documented way to set the iPhone orientation?
all credit to Josh who although not the accepted answer is the one that 99 people currently have up voted.
I still have a bug in that, if I were holding the device in landscape (although the display is portrait view) whilst on the screen that segues into the diveSiteDetailsController then the initial view the diveSiteDetailsController display will be in landscape.
To get around this I created a Bool property called notThisTime on the diveSiteDetailsController and set it to true in the prepareFor Segue on the viewController that called it.
i then did changed supportedInterfaceOrientation to
- (NSUInteger)supportedInterfaceOrientations
{// DLog(#"Running %# '%#'", self.class, NSStringFromSelector(_cmd));
if (self.notThisTime){
return UIInterfaceOrientationMaskPortrait;
}
if (!self.dsDataRangeSlidingTV.hidden) {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
then at the end of the ViewDidLoad method I added
self.notThisTime = NO;
I would still love to hear from anyone with a suggestion how better to handle this. pushing and popping a dummy view to get the iPhone to do an orientation check seems like a work around for something that should just be available as a standard method call.
One final Note - the iOS simulator does not like this - you need to check on the device - it sometimes tries to draw the iPhone container in landscape while the screen is drawn vertically - however it does work fine on the iPhone
My Project have 2 views 1. Mainview controller 2. Settingview Controller .
I want my main view controller to support all orientations but the setting view controller should be in landscape mode irrespective of the device orientation. Right now I am facing issues like
1. Even if the scene is in landscape mode the view appears as portrait
2. (BOOL)shouldAutorotate , (NSUInteger)supportedInterfaceOrientations not getting fired.
Any help is appreciated.
When I'm in landscape mode on iPad and trying to launch app I'm getting strange behavior:
My root view controller view is created with dimensionality equal to 768x1024 whereas it should be 1024x768 (device is in landscape mode). Because of that my view hierarchy is corrupted.
View is created by the system (I'm using nib for interface).
Does it bug in iOS, or, maybe, I'm doing something wrong?
Edit: Autoresizing mask is default (everything resizes).
Found a solution here Reporting incorrect bounds in landscape Mode.
I was checking view controller view size in viewDidLoad, while correct sizes available only in viewDidAppear.
That is ok. It is always creates views in portrait orientation when perform rotation to lanscape. So U should implement
- (BOOL) shouldAutorotateToInterfaceOrientation (UIInterfaceOrientation)
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)
And check in code
I have some 10 view controllers contained in a TabBarController. We have a requirement wherein one view controller out of these 10 view controllers should always be displayed in landscape mode.
Now, when we override:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
and return YES only for Landscape mode in such view controllers, it has not effect. The view controller appears in Portrait mode only.
Probably this is done for a good reason, since when the user switches to a tab whose view controller should support only landscape mode, the whole screen components (including the tabbar) should be rotated to landscape mode, which looks awkward.
Am I right in assuming the cause?
Also, what would be the best way to tackle this? Provide an intermediate view controller in portrait mode and then push the landscape view controllers through it?
Thanks,
Raj