I'm having trouble switching between two subclassed CollectionViewFlowLayouts.
I call the following method in my collectionViewController:
header:
#property (nonatomic, strong) PortraitFlowLayout *portraitFlowLayout;
#property (nonatomic, strong) LandscapeFlowLayout *landscapeFlowLayout;
Implementation:
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
if (UIDeviceOrientationIsPortrait(toInterfaceOrientation)) {
self.landscapeFlowLayout = nil;
[self portraitFlowLayout];
NSLog(#"Orientation portrait");
} else {
self.portraitFlowLayout = nil;
[self landscapeFlowLayout];
NSLog(#"Orientation landscape");
}
[self.collectionView.collectionViewLayout invalidateLayout];
}
and in the same collectionViewController:
- (LandscapeFlowLayout *)landscapeFlowLayout
{
if (_landscapeFlowLayout == nil) {
_landscapeFlowLayout = [[LandscapeFlowLayout alloc] init];
self.collectionView.collectionViewLayout = _landscapeFlowLayout;
}
[self.collectionView.collectionViewLayout invalidateLayout];
return _landscapeFlowLayout;
}
- (PortraitFlowLayout *)portraitFlowLayout
{
if (_portraitFlowLayout == nil) {
_portraitFlowLayout = [[PortraitFlowLayout alloc] init];
self.collectionView.collectionViewLayout = _portraitFlowLayout;
}
[self.collectionView.collectionViewLayout invalidateLayout];
return _portraitFlowLayout;
}
I know that both layout are valid, and working, since I'm pushing into this viewController form another viewCont, and I've tried to do it with both the landscape and the portrait layout, which works fine.
The problem arises when I change the orientation. The first orientation change is fine, and the layout change as it's supposed to. But when it's then rotated back (sometimes it will rotate back and forth a few times before crashing), it gives me the following error when I trace it with the Zombie template in Instruments:
How can I trace this error further? Or, fix the problem? Any help is greatly appreciated.
Thanks in advance
EDIT
The problem seems only to arise when rotating to portrait.
Chris
Try to use UIDeviceOrientationDidChangeNotification instead willRotateToInterfaceOrientation.
This lines from the Apple's docs:
To support an alternate landscape interface, you must do the following:
Implement two view controller objects. One to present a portrait-only interface, and the other to present a landscape-only interface.
Register for the UIDeviceOrientationDidChangeNotification notification. In your handler method, present or dismiss the alternate view controller based on the current device orientation.
- (void)awakeFromNib
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
//without selector event may be lost
[self performSelector:#selector(updateFrameWithOrientation) withObject:nil afterDelay:0];
}
-(void) updateFrameWithOrientation{
UIInterfaceOrientation deviceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation))
{
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation))
{
}
[self.collectionView reloadData];
}
Related
There are one UIScrollView and it has two pages, the first page in the UIScrollView I want to enable landscape orientation and the second page in the UIScrollView I want to disable the landscape orientation,now I am use this code as below,but it work not perfected,the second page will horizontal screen and then portrait screen:
- (void)viewWillAppear:(BOOL)animated {
[ITNotificationCenter addObserver:self selector:#selector(handleDeviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)handleDeviceOrientationDidChange{
if(isFirstPage){
//landscape code
} else {
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}
}
How can I achieve this? Every answer will be appreciated.
The problem has been solved. Just see the code as below.
AppDelegate.h file:
#property (nonatomaic, assign, getter=isNeedRotation) BOOL needRotation;
AppDelegate.m file:
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (self.isNeedRotation) {
return UIInterfaceOrientationMaskPortrait;
}
return UIInterfaceOrientationMaskAllButUpsideDown;
}
yourUIViewController.m file:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.mainScrollView) {
AppDelegate *appDelegate = (AppDelegate *)ITUIApplicationDelegate;
if (scrollView.contentOffset.x < screen_width) {
appDelegate.needRotation = YES;
} else {
appDelegate.needRotation = NO;
}
}
}
When a certain button is pressed in my app, the view should change orientation from portrait to
landscape. When the user comes back, the view controller should change back to portrait. But
sometimes the orientation doesn't change or the wrong view frame is used.
Here is my code
-(void)btnSignClicked:(CustomSignButton *)btn {
isSignButtonClicked = true;
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_0) {
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}
else
{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
}
selectedWaiverId = btn.customTag;
SignatureView *obj = [[SignatureView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) delegate:self]; // Most of time got size (568,320) but some time i got (320,568), Don't know why
[self.view addSubview:obj];
}
#pragma mark - SIGNATUREVIEW DELEGATE
-(void)removeSignatureView:(SignatureView *)signatureView {
isSignButtonClicked = false;
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_0)
{
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"]; // Some time not changed the orientation are view remaining in landscape
}
else
{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
}
[signatureView removeFromSuperview];
signatureView = nil;
}
#pragma mark
#pragma mark - Rotate screen
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if (isSignButtonClicked == true)
{
return UIInterfaceOrientationMaskLandscapeRight|UIInterfaceOrientationMaskLandscape;
}
else
{
return UIInterfaceOrientationMaskPortrait;
}
}
- (BOOL)shouldAutorotate
{
return YES;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (isSignButtonClicked == true)
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
else
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
}
UPDATE
Sometimes viewWillTransitionToSize method is not called so I also integrate this notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
But sometimes this also does not work.
Add in AppDelegate.m file or any base controller file
#implementation UINavigationController (Orientation)
- (UIInterfaceOrientationMask) supportedInterfaceOrientations
{
return [(UIViewController*)[[self viewControllers] lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [(UIViewController*)[[self viewControllers] lastObject] preferredInterfaceOrientationForPresentation];
}
- (BOOL) shouldAutorotate
{
return [(UIViewController*)[[self viewControllers] lastObject] shouldAutorotate];
}
#end
Now put your ViewController object in UINavigationController object and push the view controller.
EX.
UINavigationController *obj=[[UINavigationController alloc] initWithRootViewController:_yourViewCtrlObj];
[self presentViewController:obj.....];
or
[self.navigationController pushViewController:obj animated:YES];
Set your desired orientation in all view controller.
If your app uses UINavigationViewController then create a custom class for UINAvigationController Like:
//CustomNavViewController.h
#import <UIKit/UIKit.h>
#interface CustomNavViewController : UINavigationController <UINavigationControllerDelegate>
#end
//CustomNavViewController.m
#import "CustomNavViewController.h"
#interface CustomNavViewController ()
#end
#implementation CustomNavViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)shouldAutorotate {
return [self.visibleViewController shouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.visibleViewController supportedInterfaceOrientations];
}
#end
And Now in your AppDelegate declare a property Like:
//AppDelegate.h
#property (assign, nonatomic) BOOL shouldRotate;
//AppDelegate.m
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (self.shouldRotate) {
return UIInterfaceOrientationMaskLandscapeLeft|UIInterfaceOrientationMaskLandscapeRight;
}
return UIInterfaceOrientationMaskPortrait;
}
Now you can call orientation methods to ViewController which required fix orientation Like:
//YourViewController.m
-(BOOL)shouldAutorotate{
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationLandscapeLeft;
}
Now here is the trick set AppDelegate shouldRotate property to true and false for desired orientation
if you are using Default Presentation for ViewController then
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate setShouldRotate:true];// Remember first update the value then present the ViewController
[self presentViewController:yourViewController animated:YES completion:nil];
Same as when you dismiss
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate setShouldRotate:false];
[self dismissViewControllerAnimated:YES completion:nil];
If you are using storyBoards then add CustomNavViewController directly on Identity Inspector Custom class section
And after that follow above steps. Hope it's working
When you say "When the user comes back, the view controller should change back to portrait", do you mean that the user is hitting the back button on a navigation controller? If so, I saw this issue before and posted a solution that worked for me in another SO post: A: Locking device orientation on a view fails when going back in NavBar. I remember the transition being rough but it worked.
I also wrote a blog post a while back that looks at some other situations around view controller orientation locking.
See this link, in particular, I think you should check the conditions of your view controllers, that they meet Apple recommendations
e.g. check supportedInterfaceOrientations method of the top-most full-screen view controller
Try adding all your rotation changing code inside this block
dispatch_async(dispatch_get_main_queue(),
{
//changing orientation code + isSignButtonClicked = true (or false)
});
You need not use shouldAutorotate and shouldAutorotateToInterfaceOrientation.
As for the view frames getting wrong, you need to use autolayout constraints for each and every view you are using in this viewController even if you are creating views programmativally
My app accepts only portrait orientation, except for MPMoviePlayerController, which I want to allow user to change orientation.
So, I subclassed UINavigationController and added the following code:
-(BOOL)shouldAutorotate
{
if ([[[self.viewControllers lastObject] presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]])
{
return YES;
}
else
{
return NO;
}
}
It works great, allowing only my MPMoviePlayerViewController to change orientation. The problem is that when user is in landscape orientation and presses the done button or playback ends, it pops the moviePlayer and goes back to the presentingViewController, but on landscape mode, causing a crash, since that view is not made for landscape orientation.
I tried a few things to change back to Portrait but had no luck. I'm using storyboards, if that makes any difference. I would like to change the orientation back to portrait on viewWillAppear, or maybe getting the donebutton press and change the orientation there.
UPDATE:
Here is the updated code in my UINavigationControllersubclass:
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
if ([[[self.viewControllers lastObject] presentedViewController] isKindOfClass:[MPMoviePlayerViewController class]])
{
return UIInterfaceOrientationMaskAll;
}
else
{
return UIInterfaceOrientationMaskPortrait;
}
}
Now, if I do things in the following order from the view with the Play button.
Rotate the device. (it calls the method but screen doesn't rotate since it is not MPMoviePlayerController class)
Press the play button. (It presents the player already on landscape mode).
Press the back button. (It pops the player and correctly shows the view on portrait mode)
Now, if I change the order to:
Press the play button. (holding the device on the regular portrait position).
Rotate the device. (it rotates the movie player correctly showing the video).
Press the back button. (it pops the player, but this time, the view is in landscape mode, which is not the expected behavior)
Found a solution here on this answer.
On button click, I added a notification and then on done button click I used the below code to change orientation. I kept the UINavigationController subclass as in my question to allow the change of orientation when movie starts playing.
- (IBAction)playButton:(id)sender {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackDidFinish)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.player.moviePlayer];
NSURL *url = [NSURL URLWithString:#"https://dl.dropboxusercontent.com/s/crzu6yrwt35tgej/flexao.mp4"];
self.player = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
self.player.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[self presentMoviePlayerViewControllerAnimated:self.player]; // presentMoviePlayerViewControllerAnimated:self.player];
}
-(void)moviePlaybackDidFinish
{
[[UIDevice currentDevice] setValue:
[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
forKey:#"orientation"];
}
I have a working configuration for your problem, as far as I understand from your question.
You need a subclass of UINavigationController as you already have, but with the following code:
The .h file:
#interface EECNavigationController : UINavigationController
#property (assign, nonatomic) BOOL landscapeDisallowed;
#end
The .m file:
#import "EECNavigationController.h"
#implementation EECNavigationController
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
if( !_landscapeDisallowed ) {
// for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
#end
Now, in the view controllers that will be under this navigation controller that you want to be just portrait you just need to set the "landscapeDisallowed" to YES in the viewDidLoad method, like:
- (void)viewDidLoad {
[super viewDidLoad];
((EECNavigationController *)self.navigationController).landscapeDisallowed = YES;
}
And override the following methods like this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return toInterfaceOrientation == UIInterfaceOrientationPortrait;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
The views that can be presented in landscape mode just need to:
- (void)viewDidLoad {
[super viewDidLoad];
((EECNavigationController *)self.navigationController).landscapeDisallowed = NO;
}
It works for me, hope it works for you.
-(void)viewWillAppear:(BOOL)animated
{
[self updateLayoutForNewOrientation:self.interfaceOrientation];
}
- (void)updateLayoutForNewOrientation:(UIInterfaceOrientation)orientation
{
if (self.interfaceOrientation == UIInterfaceOrientationPortrait || self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
// Portrait view
if(iPhone5)
{
}else{
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0"))
{
}
}
else
{
// Landscape view
if(iPhone5)
{
}else{
float SystemVersion=[[[UIDevice currentDevice] systemVersion] floatValue];
if(SystemVersion>=7.0f)
{
}else{
}
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0"))
{
if(iPhone5)
{
}
else
{
}
}
}
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
[self updateLayoutForNewOrientation:self.interfaceOrientation];
}
Hope this will help
Please don't suggest me it is a bad idea to have the rotation at ios 4.3-6.0 in 1 build, because I told to many times and didn't listen to me.
At project settings I have setted all interface orientations to be supported, just to be sure.
Right now I am testing on ios6 with iphone4. Starting at app delegate it is a code, like this:
mainController = [[MainViewController alloc] initWithNibName:nil bundle:nil];
navigationController=[[RotatingNavigationController alloc] initWithRootViewController:mainController];
navigationController.navigationBar.hidden =true;
// ios: 4 and 5
//[window addSubview:navigationController.view];
//ios6:
window.rootViewController = navigationController;
[window makeKeyAndVisible];
So I did 2 custom classes, which are recommended in may cases for autorotations, and for they the problem is solved.
The RotatingNavigationController is a custom UINavigationController has a bit ugly code, but I have collected this parts from this forum, so it should be allowed to post it:
#implementation RotatingNavigationController
- (id)init {
self = [super init];
if (self) {
self.view.autoresizesSubviews = YES;
[self.view setAutoresizingMask:(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth)];
}
return self;
}
// ios6 require this method for rotation detection, available from ios5, ios4.3 not available: sux
//- (void)viewWillLayoutSubviews
//{
//UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation;
//[[NSNotificationCenter defaultCenter] postNotificationName:UIDeviceOrientationDidChangeNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
/*
if(UIInterfaceOrientationIsLandscape(statusBarOrientation)){
[self willRotateToInterfaceOrientation: statusBarOrientation duration: 0.3 ];
}
else{
[self willRotateToInterfaceOrientation: statusBarOrientation duration: 0.3 ];
}
*/
//}
//ios 4.3 and ios 5.0, at ios6 it isn't called by iOS...sux
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
[self.visibleViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
// //ios 4.3 and ios 5.0, at ios6 need different methods, which sux
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
//Autorotation is changing in iOS 6. In iOS 6, the shouldAutorotateToInterfaceOrientation: method of UIViewController is deprecated. In its place, you should use the supportedInterfaceOrientationsForWindow: and shouldAutorotate methods.
// ios6
- (NSUInteger)supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskAll;
}
// ios6
- (BOOL)shouldAutorotate
{
return YES;
}
// ios6
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationMaskPortrait;
}
#end
this should generate the autorotation notifications properly, I think he it does his job.
The MainViewController is a custom UIViewController.
just to be sure I have copy-pasted the code:
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
// return (interfaceOrientation == UIInterfaceOrientationPortrait);
return YES;
}
// ios6:
- (NSUInteger)supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskAll;
}
// ios6
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationMaskPortrait;
}
His job is to change the different UIViewController based on device state ( rotations )
I have somewhere a Menu screen, which has different xib, but h and m file too ( because has different elements, which doesn't appear in Portait or Landscape. ( I don't have the power to change the whole architecture )
A part of the code - and here should be some problem, I think is below in this Maincontroller:
#pragma mark
#pragma mark Rotation
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(deviceOrientation == UIDeviceOrientationFaceUp || deviceOrientation == UIDeviceOrientationFaceDown){
if(debug){
NSLog(#"Nothing to change because it is gone to Flat");
}
return;
}
NSArray *viewControllers = [self.navigationController viewControllers];
if (UIDeviceOrientationIsLandscape(deviceOrientation)){
//if(debug)
// NSLog(#"Portait -> Landscape size : %3.0fw, %3.0fh", self.view.bounds.size.width, self.view.bounds.size.height);
id lastviewController = viewControllers.lastObject;
// check what is there:
if([lastviewController isKindOfClass:[MenuController class]]){
[self.navigationController popViewControllerAnimated:NO];
[self.navigationController pushViewController:menuLandscape animated:NO];
NSLog(#"poped Menu Portrait, pushed Menu Landscape");
}
...
else if(UIDeviceOrientationIsPortrait(deviceOrientation)){
//else if(UIInterfaceOrientationIsLandscape(statusBarOrientation)){
//if(debug)
// NSLog(#"Landscape -> Portait , size : %3.0fw, %3.0fh", self.view.bounds.size.width, self.view.bounds.size.height);
id lastviewController = viewControllers.lastObject;
// check what is there:
if([lastviewController isKindOfClass:[MenuLandscapeController class]]){
[self.navigationController popViewControllerAnimated:NO];
[self.navigationController pushViewController:menuPortait animated:NO];
}
...
The problem is: the landscape is taken out and is pushed the portait, when is upside down, but that portait aren't rotating and it shows a broken layout.
How can I wake up that controller and tell him is time to rotate, because it isn't in portrait mode?
Thanks any suggestion related to my question of any improvement beside of architecture change.
Update:
at app delgate doesn't helped adding the:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskAll;
}
code from other answer: presented here
Update2:
UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation;
doesn't want to take the UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown value for some reason, I think that need to be solved.
Update3:
Read very carefully twice and third the ios6 release notes
The system determines whether an orientation is supported by
intersecting the value returned by the app’s
supportedInterfaceOrientationsForWindow: method with the value
returned by the supportedInterfaceOrientations method of the top-most
full-screen controller.
now read again :)
Add this category to viewcontroller which doesn't rotate
#implementation UINavigationController(Rotation)
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
#end
Update: I found why it was loading the same view the whole time. I now fixed that. It was a typo
ControllerForSplitViews.m
- (id)init
{
self = [super initWithNibName:#"ControllerForSplitViews" bundle:nil];
if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation)){
self.view = landscapeView;
}
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
self.view = portraintView;
}
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
return self;
}
This works.
Now the problem. When the view is loaded and running I change the orientation and load a different view from the same nib file, Fixed: but as soon as I do this the other UI elements disappears and only the ui elements of my landscape view is kept and when I rotate the device again it doesn't load my portrait view again? Any suggestions why this might happen?
-(void) orientationChanged:(id)object
{
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
{
self.view = portraintView;
}
if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
self.view = landscapeView;
}
}
New Problem, each time I change the orientation it loads the opposite orientation's view
Thanks
I am adding this here as well for incase someone ever reads this, they might want to check out this post here where a simular scenario was discussed
Two views Multiple UIPickerViews Single outlet
Ok so I found a fix that works, but I have no idea why my original code didn't work what I did was:
Remove:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
Remove:
-(void) orientationChanged:(id)object
{
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
{
self.view = portraintView;
}
if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
self.view = landscapeView;
}
}
Change:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight))){
self.view = landscapeView;
}else if(((interfaceOrientation == UIInterfaceOrientationPortrait) ||
(interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown))){
self.view = portraintView;
}
return YES;
}
And now it works perfectly