I have a single storyboard where a majority of the views should be in portrait mode but one should be in Landscape. I've down a significant amount of searching but keep coming up a little blank.
My current implementation which isn't exactly seeming to work as I hoped consists of the following bits of code I've pieced together from this website:
I've made a RotationalViewController which extends from UINavigationController
#import "RotationControlledViewController.h"
#interface RotationControlledViewController ()
#end
#implementation RotationControlledViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (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.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
UIInterfaceOrientation ret = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
return ret;
}
#end
And then I've made a PortraitViewController
#import "PortraitViewController.h"
#interface PortraitViewController ()
#end
#implementation PortraitViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (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 YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
and a LandscapeViewController
#import "LandscapeViewController.h"
#interface LandscapeViewController ()
#end
#implementation LandscapeViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (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 YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationLandscapeRight | UIInterfaceOrientationLandscapeLeft;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
#end
I have played around with changing some of the settings but to no avail. My general plan of attack has been to make specific view controllers inherit from either LandscapeViewController or PortraitViewController if I want to lock them to a specific orientation.
Things seem to be working for portrait view ( i can lock controllers into portrait view) but I seem unable to load my 1 landscape view and have it a) auto rotate to landscape upon load, or b) rotate to landscape at all.
Any suggestions would be very appreciated.
Applying the solution presented in:
Force controllers to Change their orientation in Either Portrait or Landscape
I was able to make things work.
In both my PortraiteViewController and LandscapeViewControllers I modified the viewDidLoad method to:
PortraiteViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
UIViewController *mVC = [[UIViewController alloc] init];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
LandscapeViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:YES];
UIViewController *mVC = [[UIViewController alloc] init];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
This solution MAY stop working after IOS7 because both presentModalViewController and dismissModalViewController are deprecated.
Related
I've created a gradient using Quartz, only one issue. I can't get it to rotate with the screen. I've tried everything listed on this tutorial. Here's the view controller header:
#import <UIKit/UIKit.h>
#interface RadialGradientBackgroundViewController : UIViewController {
}
#end
And here's the view controller:
#import "RadialGradientBackgroundViewController.h"
#import "BackgroundLayer.h"
#implementation RadialGradientBackgroundViewController
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
CAGradientLayer *bgLayer = [BackgroundLayer gradient];
bgLayer.frame = self.view.bounds;
[self.view.layer insertSublayer:bgLayer atIndex:0];
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[[[self.subview.layer sublayers] objectAtIndex:0] setFrame:self.view.bounds]; // Error is here!
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[super dealloc];
}
#end
Your view controller does not have a subview property or method. As rmaddy said, change subview to view.
I have posted a question here . In which one buddy replied and gave solution. Although the solution is working on few view controllers but on view its not working. When I enter a view controller that has TabController + navigation controller on there tab Bar Items, the code doesn't work. and the views are able to rotate.
I used the Following code for iOS 6.1
//For iOS6
- (BOOL)shouldAutorotate {
return NO;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
I have to implement the same thing in iOS 7 too.
Please Help
shouldAutorotate, supportedInterfaceOrientations, preferredInterfaceOrientationForPresentation
The above methods don't get called of a viewcontroller if they are inside any tabbarcontroller of navigationcontroller. If these methods are declared inside tabbarcontroller or navigation controller then they will get called.
For solving this make a class FixedOrientationTab, it is a subclass of UITabBarController, and a navigation class OrientationEnabledNavigation, it is a subclass of UINavigationController. Then implemented shouldAutorotate, supportedInterfaceOrientations, preferredInterfaceOrientationForPresentation methods inside FixedOrientationTab and OrientationEnabledNavigation.
OrientationEnabledNavigation.h
#import <UIKit/UIKit.h>
#interface OrientationEnabledNavigation : UINavigationController
#end
OrientationEnabledNavigation.m
#import "OrientationEnabledNavigation.h"
#interface OrientationEnabledNavigation ()
#end
#implementation OrientationEnabledNavigation
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
// return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
FixedOrientationTab.h
#import <UIKit/UIKit.h>
#interface FixedOrientationTab : UITabBarController
#end
FixedOrientationTab.m
#import "FixedOrientationTab.h"
#interface FixedOrientationTab ()
#end
#implementation FixedOrientationTab
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (BOOL)shouldAutorotate
{
return [self.selectedViewController shouldAutorotate];
// return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Then if you want to use navigation controller in your project then use OrientationEnabledNavigation and for tabbar FixedOrientationTab. After that if you implement shouldAutorotate, supportedInterfaceOrientations, preferredInterfaceOrientationForPresentation these method inside your viewcontroller then they will get called.
Hope this helps.. :)
Edit
As Jeev pointed out another way is that add some code beginning of your app delegate:
For UITabBarController
#implementation UITabBarController (AutoRotationForwarding)
-(BOOL)shouldAutorotate
{
if ([self.selectedViewController respondsToSelector:#selector(shouldAutorotate)]) {
return [self.selectedViewController shouldAutorotate];
}
else {
return YES;
}
}
- (NSUInteger)supportedInterfaceOrientations {
if ([self.selectedViewController respondsToSelector:#selector(supportedInterfaceOrientations)]) {
return [self.selectedViewController supportedInterfaceOrientations];
}
else {
return UIInterfaceOrientationMaskAll;
}
}
#end
For UINavigationController
#implementation UINavigationController (AutoRotationForwarding)
-(BOOL)shouldAutorotate
{
if ([self.topViewController respondsToSelector:#selector(shouldAutorotate)]) {
return [self.topViewController shouldAutorotate];
}
else {
return YES;
}
}
-(NSUInteger) supportedInterfaceOrientations {
if([self.topViewController respondsToSelector:#selector(supportedInterfaceOrientations)])
{
return [self.topViewController supportedInterfaceOrientations];
}
return UIInterfaceOrientationMaskPortrait;
}
#end
I have UINavigationController contains UIViewController.
You should disable rotate in UINavigationController by subclass UINavigationController and implement
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
// return some
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
// return some thing that you want
}
Hope this helps you.
Since I m using a TabBarController, the only working solution I got was to create a category.
so just make a category
here's the .h class of the category, I named it AutoRotationtab
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#interface UITabBarController (AutoRotationTab)
#end
here's the .m class of the category
#import "UITabBarController+AutoRotationTab.h"
#implementation UITabBarController (AutoRotationTab)
-(BOOL)shouldAutorotate
{
if(globalvariable_shouldRotate)
{
return YES;
}
else
{
return NO;
}
}
- (NSUInteger)supportedInterfaceOrientations
{
if(globalvariable_shouldRotate)
{
return UIInterfaceOrientationMaskAll;
}
else
{
return UIInterfaceOrientationMaskPortrait;
}
}
just make this category, and see the Magic, It works
I am having issues with Storyboards AutoRotation and the iPhone. I've put together a VERY simple project with 3 view controllers which I uploaded to gitHub to demonstrate the issue
I've tested this on the following devices:
IPAD 3
IPHONE 5s
Simulator (iphone / ipad)
Everything seems to work perfectly on the iPad & Simulator (Iphone/Ipad) but when I run it on the 5s it does not rotate correctly.
On the iPhone it will rotate the alert view but not the view controller it appears
On the simulator this is the result (which looks correct)
Code for sample project can be found at:
https://github.com/jlss/RotationIssues
I am happy and willing to try ANY suggestions anybody has.
Things of Note: (I am using the call objc_msgSend([UIDevice currentDevice], #selector(setOrientation:), UIInterfaceOrientationLandscapeLeft); ) but as far as I can tell this should be ok.
RotationControlledViewController.m
//
// RotationControlledViewController.m
// ASGAARD
//
// Created by Jeff Stein on 2/16/14.
// Copyright (c) 2014 Jeff Stein. All rights reserved.
//
#import "RotationControlledViewController.h"
#interface RotationControlledViewController ()
#end
#implementation RotationControlledViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (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
{
BOOL ret = [[self.viewControllers lastObject] shouldAutorotate];
// NSLog(#"--Auto Roatate Reported %d", ret);
return ret;
}
-(NSUInteger)supportedInterfaceOrientations
{
NSUInteger ret = [[self.viewControllers lastObject] supportedInterfaceOrientations];
// NSLog(#"--supportedInterfaceOrientations: %d", ret);
return ret;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
UIInterfaceOrientation ret = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
// NSLog(#"--preferredInterfaceOrientationForPresentation: %ld",ret);
return ret;
}
#end
PortraitViewController.m
//
// PortraitViewController.m
// ASGAARD
//
// Created by Jeff Stein on 2/16/14.
// Copyright (c) 2014 Jeff Stein. All rights reserved.
//
#import "PortraitViewController.h"
#import "objc/message.h"
#interface PortraitViewController ()
#end
#implementation PortraitViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
objc_msgSend([UIDevice currentDevice], #selector(setOrientation:), UIInterfaceOrientationPortrait);
}
- (void)viewDidAppear:(BOOL)animated {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Portrait Alert" message:#"This is portrait view" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil];
[alert show];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
#end
LandscapeViewController
//
// LandscapeViewController.m
// ASGAARD
//
// Created by Jeff Stein on 2/16/14.
// Copyright (c) 2014 Jeff Stein. All rights reserved.
//
#import "LandscapeViewController.h"
#import "objc/message.h"
#interface LandscapeViewController ()
#end
#implementation LandscapeViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
objc_msgSend([UIDevice currentDevice], #selector(setOrientation:), UIInterfaceOrientationLandscapeLeft);
NSLog(#"Issuing a rotation message (hopefully");
}
- (void)viewDidAppear:(BOOL)animated {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Landscape Alert" message:#"This is landscape view" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil];
[alert show];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
#end
And lastly i have a simple storyboard with:
Unfortunately you cannot do this if you are using push segues. You have to use modal.
I have a master utility application embedded in a tab bar. Now, for this tab bar, i have the following.
#interface MainTabViewController : UITabBarController< UITabBarControllerDelegate>{
}
#end
#implementation MainTabViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
NSLog(#"One");
if(self.tabBarController.selectedIndex==1)
{
NSLog(#"clicked");
}
if (self.tabBarController.selectedIndex==2) {
NSLog(#"Helo");
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.tabBarController.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
The code is not reaching the didSelectViewController at all. I am new to IOS. Could anyone plz guide where i am going wrong??
Add delegate method to the UITabBarController
either using storyboard (if you are using)
or as it is UITabBarController do using
self.delegate = self ;
I have an app I am working on, and I am trying to have the logo on for a bit longer, and fade out/slide out/effect when it's done.
Here's my setup:
The Tab Bar controller is not letting me place an Image View inside it, so I created a view to have it on.
I am trying to have the logo stay on for a bit, fade out, then automatically switch the view (Segue) to the Tab Bar controller.
This is what I get out of it: http://youtu.be/l4jL0BfpR2k
So here's my code:
//
// BDNLogoViewController.m
// Bronydom Network
//
// Created by name on 10/1/13.
// Copyright (c) 2013 name. All rights reserved.
//
#import "BDNLogoViewController.h"
#import "BDNTabBarController.h"
#import "BDNFirstViewController.h"
#interface BDNLogoViewController ()
#end
#implementation BDNLogoViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[UIView animateWithDuration:1 animations:^{
_imageview.alpha = 0;
}];
//BDNTabBarController *viewController = [[BDNTabBarController alloc] init];
//[self.navigationController pushViewController:viewController animated:YES];
(void)#selector(seguePerform:);
}
- (void)seguePerform:(id)sender
{
//BDNTabBarController *myNewVC = [[BDNTabBarController alloc] init];
// do any setup you need for myNewVC
[self performSegueWithIdentifier:#"open" sender:sender];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Yes, "open" is defined as the segue id.
Do you guys have any ideas on how I could fix this?
To fix, add this
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
[self performSegueWithIdentifier:#"open" sender:self];
}
Remove this from your code
(void)#selector(seguePerform:);
// and all other unnecessary segue stuff you had