Switch View in XIB based on orientation - uiview

I have two views inside my XIB for each orientation. They are similar but different so I cannot rely on the autoresizing. I want to switch these views based on the orientation. When I use the method didRotateFromInterfaceOrientation then when it rotates from Portrait it will show the landscape view, this is a problem when it is rotating to PortraitUpsideDown.
And if I modify the code for willRotateToInterfaceOrientation then in LandscapeView the PortraitView is hidden from the user but when the user clicks the buttons they do not show gray out to show that they were clicked and it app responds as if the user is clicking the buttons that are in the portrait view.
Am I going about this problem in the right manner? What do I need to do to fix these errors. I would prefer to use the method willRotateToInterfaceOrientation.
Thanks,
CODE:
- (void)viewDidLoad {
...
for (UIView *v in self.view.subviews) {
v.autoresizingMask = UIViewAutoresizingNone;
}
...
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if(fromInterfaceOrientation == UIInterfaceOrientationPortrait
|| fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
//Add landscape view
if(![landscapeView superview]){
for (UIView *v in landscapeView.subviews) {
v.autoresizingMask = UIViewAutoresizingNone;
}
//No effect after testing
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.33];
[self.view addSubview:landscapeView];
[UIView commitAnimations];
}
}else {
if([landscapeView superview]){
[landscapeView removeFromSuperview];
}
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft
|| toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
//Add landscape view
if(![landscapeView superview]){
for (UIView *v in landscapeView.subviews) {
v.autoresizingMask = UIViewAutoresizingNone;
}
//No effect after testing
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.33];
[self.view addSubview:landscapeView];
[UIView commitAnimations];
}
}else {
if([landscapeView superview]){
[landscapeView removeFromSuperview];
}
}
}

In Your View Did Load
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(willRotateToInterfaceOrientation:)
name:#"UIDeviceOrientationDidChangeNotification" object:nil];
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) {
viewControllerName *newView = [[viewControllerName alloc] initWithNibName:nil bundle:nil];
newView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:newView animated:YES];
[newView release];
}
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight) {
viewControllerName *newView = [[viewControllerName alloc] initWithNibName:nil bundle:nil];
newView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:newView animated:YES];
[newView release];
}
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait) {
viewControllerName *newView = [[viewControllerName alloc] initWithNibName:nil bundle:nil];
newView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:newView animated:YES];
[newView release];
}
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) {
viewControllerName *newView = [[viewControllerName alloc] initWithNibName:nil bundle:nil];
newView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:newView animated:YES];
[newView release];
}
}

Related

How to detect the orientation changing ipad

Im creating an iPad application that should be supported both landscape and portrait. I have set root view controller in AppDelegate like this. This view is my Splash screen view.
Inside
`
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft)
{
//Do what you want in Landscape Left
viewController1=[[SplashLandscapeViewController alloc] initWithNibName:#"SplashLandscapeViewController" bundle:nil];
}
else if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight)
{
//Do what you want in Landscape Right
viewController1=[[SplashLandscapeViewController alloc] initWithNibName:#"SplashLandscapeViewController" bundle:nil];
}
else if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait)
{
//Do what you want in Portrait
viewController1=[[SplashLandscapeViewController alloc] initWithNibName:#"SplashViewController" bundle:nil];
}
else if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
//Do what you want in Portrait Upside Down
viewController1=[[SplashLandscapeViewController alloc] initWithNibName:#"SplashViewController" bundle:nil];
}
self.window.rootViewController = viewController1;
[self.window makeKeyAndVisible];
return YES;
}
And this is working fine. And this viewcontroller1 is dissmiss after 4,5 seconds and load another viewcontroller. My problem is while that viewcontroller1 showing on the screen, if user turn the ipad how can I recogniz it and load my landscape .xib after removing the current portrait xib.
Please help me.
Thank you
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(changeOrientation) name:UIDeviceOrientationDidChangeNotification object:nil];
add this method into the app view controller for getting notification.
-(void)changeOrientation {
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {
[[NSBundle mainBundle] loadNibNamed:#"Portrait" owner:self options:nil];
}
else {
[[NSBundle mainBundle] loadNibNamed:#"Landscape" owner:self options:nil];
}
}

IOS How to Make Landspace Orientation in Every Page

I'm making an ios app, I want to make all pages are landspace.
The first page is landspace, but the second page is portrait (going the second page via button).
How to make it landspace.
(I'm not using storyboard)
Button click event:
PanelController *panel = [[PanelController alloc] init];
[self.navigationController pushViewController:panel animated:true];
How about this ?
-(void)viewWillAppear:(BOOL)animated
{
UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
UIViewController *controller = [[UIViewController alloc]init];
[controller.view setBackgroundColor:[UIColor whiteColor]];
[self.navigationController presentViewController:controller animated:NO completion:^{
[self.navigationController dismissViewControllerAnimated:YES completion:^{
}];
}];
}
The correct technique for changing orientation should be this:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}

UIDeviceOrientationPortrait , ios 6 & 7 , InterfaceOrientation

i have this code i want to go to another uiview but i want to have showing this view (second view) in portrait mode only and the notification in first view doesn't work in second view ;
is there any way to change the for this
[[NSNotificationCenter defaultCenter] removeObserver:self];
view2 *viewController = [[[view2 alloc] init] autorelease];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:viewController] autorelease];
viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:navController animated:NO];
i want exactly one function same this code in ios >6
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return NO;
}
Try subclassing the UINavigationController and override the following methods :
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}

AppDelegate should call the method if the screen orientation has changed

I have a popover, which I present from the TabBarItem thats why I make it in AppDelegate, but I need to reshow popover in new place if the screen orientation has changed. In other places of my app I just use the didRotateFromInterfaceOrientation method, but it doesn't called in AppDelegate. How can I solve this?
I present a popover by this code:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
if (viewController == [self.objTabBarController.viewControllers objectAtIndex:2])
{
if (self.settingsPopover == nil) {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main - iPad" bundle: nil];
SettingsViewController *settingsController = [mainStoryboard instantiateViewControllerWithIdentifier: #"SettingsPopover"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:settingsController];
self.settingsPopover = [[UIPopoverController alloc] initWithContentViewController:navigationController];
CGSize tabBarSize = self.objTabBarController.tabBar.frame.size;
CGPoint center = [self.window.rootViewController.view convertPoint:self.objTabBarController.tabBar.center fromView:self.objTabBarController.tabBar.superview];
center.x += 105;
center.y -= tabBarSize.height / 2;
CGRect rect = {center, CGSizeZero};
[self.settingsPopover presentPopoverFromRect:rect inView:self.window.rootViewController.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
} else {
[self.settingsPopover dismissPopoverAnimated:NO];
self.settingsPopover = nil;
}
return NO;
}
}
return YES;
}
You can register a Notification as follow:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleDidChangeStatusBarOrientationNotification:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
Then, implement it in the AppDelegate:
- (void)handleDidChangeStatusBarOrientationNotification:(NSNotification *)notification;
{
NSLog(#"The orientation changed to %#", [notification.userInfo objectForKey: UIApplicationStatusBarOrientationUserInfoKey]);
}
Enjoy. :)

Can't resize height contentSizeForViewInPopover of UIViewController in side UINavigationController of UIPopover

I use UINavigationController inside UIPopoverController
-(void)showEditMenuFrom:(UIButton *)button{
if (self.popover) {
[self.popover dismissPopoverAnimated:YES];
self.popover = nil;
}
else {
EditMenuViewController *editMenuViewController = [[EditMenuViewController alloc] initWithNibName:#"EditMenuViewController" bundle:nil];
UINavigationController *actionsNavigationController = [[UINavigationController alloc] initWithRootViewController:editMenuViewController];
actionsNavigationController.delegate = self;
// switch for iPhone and iPad.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
self.popover = [[UIPopoverController alloc] initWithContentViewController:actionsNavigationController];
self.popover.delegate = self;
// CGRect presentFrame = CGRectMake(button.frame.origin.x-43, button.frame.origin.y-10, button.frame.size.width, button.frame.size.height);
[self.popover presentPopoverFromRect:button.frame inView:button permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
} else {
[self presentViewController:actionsNavigationController animated:YES completion:^{
NSLog(#"Activity complete");
}];
}
}
}
And I try to resize view inside UIPopover when navigate and these are result:
Root view:
2.Push to other VC
3.Pop back:
You can see the height of root VC can't change back to origin size.
I try to set contentSizeForViewInPopover in viewDidAppear, viewDidLoad and in UINavigationControllerDelegate but no methods work
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSLog(#"Show VIEW %#",viewController);
if ([viewController isKindOfClass:[EditMenuViewController class]]) {
viewController.contentSizeForViewInPopover = CGSizeMake(160.0, 160.0);
} else {
viewController.contentSizeForViewInPopover = CGSizeMake(320.0, 320.0);
}
}
How to solve this problem? Thanks!
I end up my question for someone meet this solution:
First, you need to declare a #property inside the VC which pop back on stack
#property (nonatomic, strong) UIPopoverController *popover;
Then assign it to UIPopoverController in main code
self.popover = [[UIPopoverController alloc] initWithContentViewController:actionsNavigationController];
self.popover.delegate = self;
editMenuViewController.popover = self.popover;
And Finally, setting the size in viewWillAppear of VC you want to resize
-(void)viewWillAppear:(BOOL)animated
{
[self.popover setPopoverContentSize:CGSizeMake(160,160)];
self.contentSizeForViewInPopover = CGSizeMake(160,160);
[super viewWillAppear:animated];
}
Try with bellow example miht be usefull:-
-(void)showEditMenuFrom:(UIButton *)button{
if (self.popover) {
[self.popover dismissPopoverAnimated:YES];
self.popover = nil;
}
else {
EditMenuViewController *editMenuViewController = [[EditMenuViewController alloc] initWithNibName:#"EditMenuViewController" bundle:nil];
UINavigationController *actionsNavigationController = [[UINavigationController alloc] initWithRootViewController:editMenuViewController];
actionsNavigationController.delegate = self;
// switch for iPhone and iPad.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
self.popover = [[UIPopoverController alloc] initWithContentViewController:actionsNavigationController];
self.popover.delegate = self;
popover.popoverContentSize =CGSizeMake(250,200); //Addint this line for setContentsize
[self.popover presentPopoverFromRect:button.frame inView:button permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
} else {
[self presentViewController:actionsNavigationController animated:YES completion:^{
NSLog(#"Activity complete");
}];
}
}
}
In EditMenuViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//self.clearsSelectionOnViewWillAppear = NO; //this work if superclass is UITableviewcontroller
self.contentSizeForViewInPopover = CGSizeMake(200,100);
}
-(void)viewWillDisappear:(BOOL)animated
{
self.contentSizeForViewInPopover = CGSizeMake(250,200);
[super viewWillDisappear:YES];
}
ADD
Check some useful similar to your issue:-
Animate popoverContentsize when pushing navigation view controller in popover on iPad
UIPopoverController automatically resizing to max height on pushViewController
push a new tableViewController in a uipopovercontroller causes the popover to be resized
Popover with embedded navigation controller doesn't respect size on back nav

Resources