switch between portrait and landscape - iphone

i have taken two views one is portrait and landscape,i want the switch the view on rotation i am using below code but its not working,may i know where i am going wrong as i am new to iphone development.i have not implemented anything in ViewDidLoad method,should i implement anything there as well?
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
self.portrait.hidden = YES;
self.landscape.hidden = NO;
} else {
self.portrait.hidden = NO;
self.landscape.hidden =YES;
}
return YES;
}

I have showed To Images in Two Views One in Horizontal and one in Vertical....
In ViewController.m:-
#interface OrientationTutorialViewController : UIViewController
{
IBOutlet UIView *portraitView;
IBOutlet UIView *landscapeView;
}
#property (nonatomic, retain) IBOutlet UIView *portraitView;
#property (nonatomic, retain) IBOutlet UIView *landscapeView;
#end
IN .h :-
#implementation OrientationTutorialViewController
#synthesize portraitView, landscapeView;
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
}
- (void) orientationChanged:(id)object
{
UIInterfaceOrientation interfaceOrientation = [[object object] orientation];
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
self.view = self.portraitView;
}
else
{
self.view = self.landscapeView;
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)dealloc
{
[super dealloc];
}
#end
Hope My Answer Helps You... If Not Please Tell me ur id I will Send u the Project.

To support orientation the function
-(Bool)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
Now to perform the action while rotation you have to use the below function
As you have two views named landscape and portrait make sure that you have linked Referencing outlets correctly
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
self.view = portrait;
}
else
{
self.view = landscape;
}
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
self.portrait.hidden = YES;
self.landscape.hidden = NO;
return YES;
}
else {
self.portrait.hidden = NO;
self.landscape.hidden = YES;
return YES;
}
}

Related

MBProgressHud is not changing with device orientation.?

I am using MBProgressHud to show a loading indicator on a splash view but this does not change with device orientation. My code is:
splashView = [[UIImageView alloc] initWithFrame:self.window.frame];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
splashView.image = [UIImage imageNamed:#"DefaultPad.png"];
}
else
{
splashView.image = [UIImage imageNamed:#"Default.png"];
}
hud = [[MBProgressHUD alloc]initWithView:splashView];
[splashView addSubview:hud];
hud.userInteractionEnabled=NO;
hud.labelText = #"Loading...";
[hud show:YES];
[self.window addSubview:splashView];
[self performSelector:#selector(Load_FirstView) withObject:nil afterDelay:3];
[self.window makeKeyAndVisible];
and I have changed the line in MBProgressHud.m file from
- (void)deviceOrientationDidChange:(NSNotification *)notification {
NSLog(#"in device orientation ");
UIView *superview = self.superview;
if (!superview) {
return;
} else if ([superview isKindOfClass:[UIWindow class]]) { // here changes have done
[self setTransformForCurrentOrientation:YES];
} else {
self.bounds = self.superview.bounds;
[self setNeedsDisplay];
}
}
to:
- (void)deviceOrientationDidChange:(NSNotification *)notification {
NSLog(#"in device orientation ");
UIView *superview = self.superview;
if (!superview) {
return;
} else if ([superview isKindOfClass:[UIImageView class]]) {
[self setTransformForCurrentOrientation:YES];
} else {
self.bounds = self.superview.bounds;
[self setNeedsDisplay];
}
}
How can I get the loading indicator to rotate with device orientation?
In MBProgressHUD.m I changed
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
to
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
The orientation notification had been received, but the statusBar had not rotated yet.
Try This:-
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
//code for portrait
[hud release];
hud = [[MBProgressHUD alloc]initWithView:splashView];
}
else
{
//code for Landscape
[hud release];
hud = [[MBProgressHUD alloc]initWithView:splashView];
}
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight ||
interfaceOrientation == UIInterfaceOrientationPortrait ||
interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
if it does not work..
you can change the UIDeviceOrientationDidChangeNotification with UIApplicationDidChangeStatusBarOrientationNotificationin the source code of MBProgressHUD:-
- (id)initWithView:(UIView *)view {
// Let's check if the view is nil (this is a common error when using the windw initializer above)
if (!view) {
[NSException raise:#"MBProgressHUDViewIsNillException"
format:#"The view used in the MBProgressHUD initializer is nil."];
}
id me = [self initWithFrame:view.bounds];
// We need to take care of rotation ourselfs if we're adding the HUD to a window
if ([view isKindOfClass:[UIWindow class]]) {
[self setTransformForCurrentOrientation:NO];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(deviceOrientationDidChange:)
name:UIDeviceOrientationDidChangeNotification object:nil];
return me;
}
In the above code change UIDeviceOrientationDidChangeNotificationwith UIApplicationDidChangeStatusBarOrientationNotification.
It is just a work-around as rotation issue was always there with MBProgressHud .
I Guess MBProgressHud is giving a lo of problems , you should instead switch to svprogresshud as it handles orientations well

didAnimateFirstHalfOfRotationToInterfaceOrientation iOS5 replacement

didAnimateFirstHalfOfRotationToInterfaceOrientation is deprecated in iOS 5.0. However I would like to use this method in my application. I am using the sample code that Apple offers in the iOS Dev Center, project name AlternateViews. I would like the app to rotate the portraitView while fading in the landscapeView. Can this be done in iOS 5 or is this feature forever gone?
portraitView currently calls:
[self presentModalViewController:self.landscapeViewController animated:YES];
while landscapeView calls this in code in the init method:
self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
It appears all of the animation is done in the following PortraitViewController.m:
#import "PortraitViewController.h"
#import "LandscapeViewController.h"
#implementation PortraitViewController
#synthesize landscapeViewController;
- (void)viewDidLoad
{
self.view.backgroundColor = [UIColor colorWithRed:197.0/255.0 green:204.0/255.0 blue:211.0/255.0 alpha:1.0];
LandscapeViewController *viewController = [[LandscapeViewController alloc]
initWithNibName:#"LandscapeView" bundle:nil];
self.landscapeViewController = viewController;
[viewController release];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)viewDidUnload
{
self.landscapeViewController = nil;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[landscapeViewController release];
[super dealloc];
}
- (void)orientationChanged:(NSNotification *)notification
{
// We must add a delay here, otherwise we'll swap in the new view
// too quickly and we'll get an animation glitch
[self performSelector:#selector(updateLandscapeView) withObject:nil afterDelay:0];
}
- (void)updateLandscapeView
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
[self presentModalViewController:self.landscapeViewController animated:YES];
isShowingLandscapeView = YES;
}
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
[self dismissModalViewControllerAnimated:YES];
isShowingLandscapeView = NO;
}
}
// override to allow orientations other than the default portrait orientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait); // support only portrait
}
#end
Here is my current implementation files which fail miserably.
PortraitViewController.m:
#import "PortraitViewController.h"
#import "LandscapeViewController.h"
#implementation PortraitViewController
#synthesize landscapeViewController;
- (void)viewDidLoad
{
LandscapeViewController *viewController = [[LandscapeViewController alloc]
initWithNibName:#"LandscapeView" bundle:nil];
self.landscapeViewController = viewController;
[viewController release];
NSLog(#"Portrait viewDidLoad");
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:NO];
}
- (void)viewDidUnload
{
self.landscapeViewController = nil;
}
- (void)dealloc
{
[landscapeViewController release];
[super dealloc];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
NSLog(#"Portrait-willAnimateRotationToInterfaceOrientation Portrait");
} else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
NSLog(#"Portrait-willAnimateRotationToInterfaceOrientation Landscape");
}
[self performSelector:#selector(updateLandscapeView) withObject:nil afterDelay:0];
}
- (void)updateLandscapeView
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
NSLog(#"Portrait-present Landscape");
[self presentModalViewController:self.landscapeViewController animated:YES];
isShowingLandscapeView = YES;
}
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
NSLog(#"Portrait-dismiss Landscape");
[self dismissModalViewControllerAnimated:YES];
isShowingLandscapeView = NO;
}
}
// override to allow orientations other than the default portrait orientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
return NO;
else
return YES;
}
#end
LandscapeViewController.m
#import "LandscapeViewController.h"
#implementation LandscapeViewController
// the designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{
self.wantsFullScreenLayout = YES; // we want to overlap the status bar.
// when presented, we want to display using a cross dissolve
self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
}
return self;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
oldStatusBarStyle = [[UIApplication sharedApplication] statusBarStyle];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:NO];
NSLog(#"Landscape viewWillAppear");
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] setStatusBarStyle:oldStatusBarStyle animated:NO];
}
// override to allow orientations other than the default portrait orientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// return YES for supported orientations
if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
return NO;
else
return YES;
//return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
NSLog(#"Landscape-willAnimateRotationToInterfaceOrientation Portrait");
[self dismissModalViewControllerAnimated:YES];
} else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
NSLog(#"Landscape-willAnimateRotationToInterfaceOrientation Landscape");
}
}
#end
In Apple's UIViewController reference page, you'll find this useful paragraph in the "Handling View Rotations" section:
If you want to perform custom animations during an orientation change,
you can do so in one of two ways. Orientation changes used to occur in
two steps, with notifications occurring at the beginning, middle, and
end points of the rotation. However, in iOS 3.0, support was added for
performing orientation changes in one step. Using a one-step
orientation change tends to be faster than the older two-step process
and is generally recommended for any new code.
To add animations for an orientation change, override the
willAnimateRotationToInterfaceOrientation:duration: method and perform
your animations there.
Could you override the willAnimateRotationToInterfaceOrientation: method to do your animations?

Overlay image in UIImagePickerController depending on device orientation

I have two overlay images that I want show in camera view depending on the device orientation - one for the horizontal and one for vertical orientation (overlay_v.png and overlay_h.png). When device is rotated from portrait to vertical orientation, overlay image should change as well.
With beginGeneratingDeviceOrientationNotifications I am able only to determine the device orientation but cannot manage to change the overlay images. Any help / different approach would be very appreciated.
- (IBAction) getPhoto:(id) sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if((UIButton *) sender == choosePhotoBtn) {
sourceCamera = false;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
} else {
sourceCamera = true;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
//overlay image (cannot dynamically switch from vertical to horizontal in here)
UIImageView *anImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"overlay_v.png"]];
anImageView.frame = CGRectMake(0, 0, anImageView.image.size.width, anImageView.image.size.height);
picker.cameraOverlayView = anImageView;
//device orientation check
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didOrientation:) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
[anImageView release];
}
[self presentModalViewController:picker animated:YES];
}
 
- (void) didOrientation: (id)object {
UIInterfaceOrientation interfaceOrientation = [[object object] orientation];
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
NSLog(#"portrait");
} else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft ){
NSLog(#"landscape");
}
}
You can't change the cameraOverlayView property once the picker is displayed. However, you can modify the view itself. Create a UIView property named overlayView. Add both images as subViews to this view and use the tag property on each image to easily grab that view again. Hide the one that shouldn't be shown for the current orientation.
- (void) didOrientation: (id)object {
UIInterfaceOrientation interfaceOrientation = [[object object] orientation];
UIImageView *pImageView = [self.overlayView viewWithTag:10];
UIImageView *lImageView = [self.overlayView viewWithTag:20];
if (interfaceOrientation == UIInterfaceOrientationPortrait ||
interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
NSLog(#"portrait");
pImageView.hidden = NO;
lImageView.hidden = YES;
} else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight ||
interfaceOrientation == UIInterfaceOrientationLandscapeLeft ){
NSLog(#"landscape");
pImageView.hidden = YES;
lImageView.hidden = NO;
}
}

How do i stop the mainView from rotating?

I have this code, set to make the clockView appear when the phone is rotated to landscape, and then to make it go back to the mainView when it's returned to portrait. But when it does go back to portrait, the portrait view is in landscape mode. How do i fix this? This is my code.
-(void)willAnimateRotationToInterfaceOrientation(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
UIInterfaceOrientation toOrientation = self.interfaceOrientation;
if(toOrientation == UIInterfaceOrientationPortrait)
{
self.view = mainView;
}
else if(toOrientation == UIInterfaceOrientationLandscapeLeft)
{
self.view = clockView;
}
else if (toOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
self.view = mainView;
}
else if(toOrientation == UIInterfaceOrientationLandscapeRight)
{
self.view = clockView;
}
}
It is probably better to have both mainView and clockView as subviews of your view controller:
// in viewDidLoad do [self.view addSubView:mainView]; [self.view addSubView:clockView]; clockView.hidden = YES;
-(void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if(UIInterfaceOrientationIsPortrait(toOrientation)) {
mainView.hidden = NO;
clockView.hidden = YES;
}
else {
mainView.hidden = YES;
clockView.hidden = NO;
}
}
This way, boths views are automatically rotated in the right way and your problem should go away.

How fix "blank" area when navigationBarHidden = NO

I'm rotating a view similar to tje iTunes app. In portrait is a tableview and in landscape is photo viewver.
When I return from landscape to portrait I try to recover the navigationbar but instead get a distorted tableview, and no navigation bar.
This is what I do:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
BOOL restoreNav = NO;
if ((toInterfaceOrientation == UIInterfaceOrientationPortrait) ||
(toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)) {
[self inPortrait];
restoreNav = YES;
} else {
[self inLandscape];
}
if (self.landscape)
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
{
self.view = self.portrait;
}
else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
self.view = self.landscape;
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
self.view = self.portrait;
}
else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
self.view = self.landscape;
}
[[self.navigationController view] setFrame: [[UIScreen mainScreen] bounds]];
} else {
self.navigationController.navigationBarHidden = NO;
}
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
I found a semi-fix for this in http://www.iphonedevsdk.com/forum/iphone-sdk-development/3262-horrible-drawing-after-hiding-navigationbar.html
This is the relevant code:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
//total hack - to fix the bug where the screen layout is shagged if the device orientation
//is changed when the navigation is hidden
if ([self.navigationController isNavigationBarHidden])
{
[self.navigationController setNavigationBarHidden:NO animated:NO];
[self.navigationController setNavigationBarHidden:TRUE animated:NO];
}
}
However, is messy again if a show up the nav bar.