Why can't I force landscape orientation when use UINavigationController? - ios

I find many question to force UIViewController to landscape as default:
How to force a UIViewController to Portrait orientation in iOS 6
And try this:
- (BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
But when I use UIViewController inside UINavigationController, I can't force to landscape.Please help!
*Work NOT ok
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navControl = [[UINavigationController alloc] initWithRootViewController:self.viewController];
[navControl setNavigationBarHidden:YES];
self.window.rootViewController = navControl;
[self.window makeKeyAndVisible];
return YES;
}
*Work OK:
self.window.rootViewController = self.viewController;

Best way to do this is the create extend UINavigationController and write your orientation function inside the extended class.
Class Declaration:
#interface MyNavigationControllerViewController : UINavigationController
#property(nonatomic, assign) UIInterfaceOrientation orientation;
#property(nonatomic, assign) NSUInteger supportedInterfaceOrientatoin;
#end
Implementation of MyNavigationController
#implementation MyNavigationController
#synthesize supportedInterfaceOrientatoin = _supportedInterfaceOrientatoin;
#synthesize orientation = _orientation;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
_supportedInterfaceOrientatoin = UIInterfaceOrientationMaskLandscape;
_orientation = UIInterfaceOrientationLandscapeLeft;
}
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 _supportedInterfaceOrientatoin;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return self.orientation;
}
#end
and use your extended like MyNavigationController as navigation controller to your rootviewcontroller.
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) ViewController *viewController;
#property (strong, nonatomic) MyNavigationControllerViewController *myNavController;
- (void) reloadAppDelegateRootViewControllerLandscape;
- (void) reloadAppDelegateRootViewController;
#end
So your application delegate didfinishlounchingwithoptions code will be as follow.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.myNavController = [[MyNavigationController alloc] initWithRootViewController:self.viewController];
[self.myNavController setNavigationBarHidden:YES];
self.window.rootViewController = self.myNavController;
[self.window makeKeyAndVisible];
return YES;
}
Only way you can provide different orientation for two different view with same navigation controller isto reload the navigation controller itself. So if you add two methods
- (void) reloadAppDelegateRootViewController{
[[[UIApplication sharedApplication].delegate window] setRootViewController:nil];
[(MyNavigationControllerViewController *)self.myNavController setOrientation:UIInterfaceOrientationPortrait];
[(MyNavigationControllerViewController *)self.myNavController setSupportedInterfaceOrientatoin:UIInterfaceOrientationMaskAll];
[[[UIApplication sharedApplication].delegate window] setRootViewController:self.myNavController];
}
- (void) reloadAppDelegateRootViewControllerLandscape{
[[[UIApplication sharedApplication].delegate window] setRootViewController:nil];
[(MyNavigationControllerViewController *)self.myNavController setOrientation:UIInterfaceOrientationLandscapeLeft];
[(MyNavigationControllerViewController *)self.myNavController setSupportedInterfaceOrientatoin:UIInterfaceOrientationMaskLandscape];
[[[UIApplication sharedApplication].delegate window] setRootViewController:self.myNavController];
}
and call these function after pushing and pop views.
Note:- I don't know whether it is a good way or bad way.

You need to go to your plist file and set the orientations. You can also do this on your project file. The plist orientations settings will override all though.
In your plist you can set both orientation options to landscape button left and landscape button right.

Related

EXC_BAD_ACCESS while textField becomeFirstResponder

I am getting EXE_BAD_ACCESS exception when I hit "back" button on NavigationBar of my CreateViewController which is pushed on UINavigationController
When I enable following line in CreateViewController.m (full code at the bottom)
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBar.hidden = NO;
//[self.textField becomeFirstResponder];
}
I start getting Thread1:EXE_BAD_ACCESS(code=1, address=...)
int main(int argc, char * argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
If I keep the above line of code disabled, then hitting back button takes me to MainViewController as expected.
I am a newbie to iOS. What I am doing wrong? Please see my code below.
Appdelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
Appdelegate.m
import "AppDelegate.h"
import "MainViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
id controller = [[MainViewController alloc] initWithNibName:#"MainView" bundle:nil];
id navController = [[UINavigationController alloc] initWithRootViewController:controller];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
#end
MainViewController.h
#interface MainViewController : UIViewController
- (IBAction)create:(id)sender;
#end
MainViewController.m
import "MainViewController.h"
import "CreateViewController.h"
#implementation MainViewController
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated {
self.navigationController.navigationBar.hidden = YES;
}
- (IBAction)create:(id)sender {
id controller = [[CreateViewController alloc] initWithNibName:#"CreateView" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
}
#end
CreateView.h
#interface CreateViewController : UIViewController <UITextFieldDelegate>
#end
CreateView.m
- (void)viewDidLoad {
[super viewDidLoad];
[self.navigationController.navigationBar setTintColor:[UIColor purpleColor]];
self.textField=[[UITextField alloc] initWithFrame:CGRectMake(80, 10, 160, 30)];
[self.textField setBorderStyle:UITextBorderStyleRoundedRect];
self.textField.placeholder = #"Name";
[self.textField setBackgroundColor:[UIColor clearColor]];
self.textField.delegate = self;
[self.navigationController.navigationBar addSubview:self.textField];
self.navigationController.navigationBar.hidden = NO;
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBar.hidden = NO;
//[self.textField becomeFirstResponder];
}
Go to breakpoint navigator and add exceptions breakpoint as shown below , 1st option :
Instead of adding self.textField as subview to navigation bar, set the textField as titleView of navigation item of the view controller.
[self.navigationItem setTitleView:self.textField];
This must help...

How to push Viewcontroller from rootViewController in iOS

I have 2 ViewController. loginViewControl which sets to rootViewControoler :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[LoginTab alloc] init];
self.window.rootViewController = loginViewControl;
[self.window makeKeyAndVisible];
return YES;
}
And I create StatusViewController :
*.h
#interface StatusViewController : UIViewController<UITabBarControllerDelegate>
{
IBOutlet UITabBarController *tabBarController;
IBOutlet UIButton *UploadButton;
IBOutlet UIButton *ConvertorButton;
IBOutlet UIButton *CompletedButton;
}
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
Now I want to push StatusViewController from loginViewControl(rootviewcontroller).I used below code but it not work.
- (IBAction)statusButtonClick:(id)sender;
{
StatusViewController *statusView = [[StatusViewController alloc]init];
[self.navigationController pushViewController:statusView animated:YES];
[statusView release];
}
Do you have any suggestions? Thanks in advance
You not setting UINavigationViewcontroller at the didFinishLaunchingWithOptions of Window's RootViewcontroller, We can't Push a UIViewController without UINavigationViewcontroller
So First Set LoginViewController as a RootViewController of UINavigationViewcontroller like Bellow:-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[YourLoinViewcontroller alloc] initWithNibName:#"YourLoinViewcontroller" bundle:nil];
UINavigationController *objNavigationController=[[UINavigationController alloc]initWithRootViewController:loginViewControl];
self.window.rootViewController = objNavigationController;
[self.window makeKeyAndVisible];
return YES;
}
EDIT
Connect your StatusViewcontroller's view with File owner like bellow:-
your push method like this:-
- (IBAction)statusButtonClick:(id)sender;
{
StatusViewController *statusView = [[StatusViewController alloc]initWithNibName:#"StatusViewController" bundle:nil];
[self.navigationController pushViewController:statusView animated:YES];
}
Unless your login view controller is a navigation controller, self.navigationController in statusButtonClick will return nil and so this won't work.
Maybe you can try:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
loginViewControl = [[LoginTab alloc] init];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:loginViewControl];
[self.window makeKeyAndVisible];
return YES;
}
This will enclose a loginViewController in a navigationController which will permit you to push another viewController in the navigationController's stack.
- (IBAction)statusButtonClick:(id)sender; {
// If used StoryBoard
UIStoryboard *story=[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
StatusViewController *statusView = [story instantiateViewControllerWithIdentifier:#"StatusViewController"];
[self.navigationController pushViewController:statusView animated:YES];
// If used XIB
StatusViewController *statusView = [[StatusViewController alloc]initWithNibName:#"StatusViewController" bundle:nil];
[self.navigationController pushViewController:statusView animated:YES]; }

UIViewController being pushed down on screen when displayed using insertSubview

Having a bit of a problem, here's the breakdown:
My AppDelegate uses as it's rootViewController a view controller. This view controller's purpose is to swap a couple of other view controllers in and out, call it login and main screens. For the sake of simplicity I've removed any swapping code from the code that I will post and am having the rootViewController simply show it's first content view controller, say login.
The issue I'm having is that the content view controller seems to be pushed down a little bit inside the rootViewController. I've given the rootViewController a blue background and the content view controller an orange background. Here's my code:
AppDelegate.h
#import <UIKit/UIKit.h>
#class MainViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) MainViewController *main;
#end
AppDelegate.m
#import "AppDelegate.h"
#import "MainViewController.h"
#implementation AppDelegate
#synthesize main;
- (void)dealloc
{
[_window release];
[main release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
MainViewController *mainVC = [[MainViewController alloc] init];
self.main = mainVC;
self.window.rootViewController = self.main;
[self.window makeKeyAndVisible];
return YES;
}
MainViewController.h
#import <UIKit/UIKit.h>
#class ContentViewController;
#interface MainViewController : UIViewController
#property (nonatomic, retain) ContentViewController *content;
#end
MainViewController.m
#import "MainViewController.h"
#import "ContentViewController.h"
#implementation MainViewController
#synthesize content;
- (id)init
{
self = [super init];
if (self ) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor blueColor];
ContentViewController *viewController = [[ContentViewController alloc] init];
self.content = viewController;
[self.view insertSubview:self.content.view atIndex:0];
}
- (void)dealloc {
[content release];
[super dealloc];
}
#end
ContentViewController.h
#import <UIKit/UIKit.h>
#interface LoginVC : UIViewController
#end
ContentViewController.m
#import "ContentViewController.h"
#implementation ContentViewController
- (id)init
{
self = [super init];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor orangeColor];
}
- (void)dealloc {
[super dealloc];
}
#end
The above codes gives me a status bar with a blue strip (approximately the height of the status bar) under it (which is the main view controller) followed by the orange content view controller taking up the rest of the screen. For some reason that main view controller seems to be pushing the content view controller down a little.
Strangely, if I create a view controller and use a XIB for drawing the view, it looks just fine and the content view it right up against the top of the main view.
If anybody could shed some light on this issue I'd very much appreciate it.
Cheers
I suppose that you shouldn't be doing
ContentViewController *viewController = [[ContentViewController alloc] init];
self.content = viewController;
[self.view insertSubview:self.content.view atIndex:0];
but rather:
ContentViewController *viewController = [[ContentViewController alloc] init];
self.content = viewController;
[self presentViewController:self.content animated:YES completion:nil];

Multiple PDFs in different tabs

I have a Tabbar iOS application with three tabs. I have each tab set up to be a UIWebView. I want each web view to display a different PDF. How do I assign, through code, each webview to its corresponding pdf?
It will look something like this in your AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
WebViewController *webViewController1 = [[WebViewController alloc] initWithPDFAtURL:#"urlToPDF1"];
WebViewController *webViewController2 = [[WebViewController alloc] initWithPDFAtURL:#"urlToPDF2"];
WebViewController *webViewController3 = [[WebViewController alloc] initWithPDFAtURL:#"urlToPDF3"];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
[tabBarController setViewControllers:[NSArray arrayWithObjects:webViewController1, webViewController2, webViewController3, nil]];
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
You will need to have a view controller that holds the UIWebView, and could look something like:
// WebViewController.h
#interface WebViewController : UIViewController
#end
// WebViewController.m
#interface WebViewController ()
#property (nonatomic, strong) NSURL *_pdfURL;
#end
#implementation WebViewController
#synthesize _pdfURL;
- (id)initWithPDFAtURL:(NSURL *)url {
self = [super init];
if (self) {
_pdfURL = url;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Load the PDF into a UIWebView
}

"Applications are expected to have a root view controller at the end of application launch"

My app was launching fine earlier today and now I'm getting this error
"Applications are expected to have a root view controller at the end of application launch"
I've looked at other threads saying to change my code, but I never changed any code to get to this point.
Delegate.h
#interface halo4AppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate>{
UIWindow *window;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
Delegate.m
#implementation halo4AppDelegate
#synthesize window;
#synthesize tabBarController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
sleep(3);
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
#pragma mark -
#pragma mark Memory management
- (void)dealloc {
[tabBarController release];
[window release];
[super dealloc];
}
#end
The xib for my FirstViewController is titles FirstView.xib , ext
This is not an error, more like a warning.
In your application delegate there is a method named application:didFinishLaunchingWithOptions: in this method you have to make this line before the end of the method self.window.rootViewController = [Some UIViewController]
again, this is not an error, you can ignore the rootViewController IF you have another way to create this rootViewController.
EDIT
This is what your method should looks like:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[viewController1, viewController2];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}

Resources