iOS 6 device orientation issue - orientation

I have 2 view controllers. I want 1st viewcontroller to be Portrait mode only while 2nd viewController should support all orientations. Please help me.
In AppDelegate class, my code is :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
UINavigationController * navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = self.viewController;
// [self.window addSubview:navController.view];
[self.window makeKeyAndVisible];
return YES;
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSLog(#"supportedInterfaceOrientationsForWindow");
return UIInterfaceOrientationMaskAllButUpsideDown;
}
1st ViewController code is:
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
// Tell the system which initial orientation we want to have
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationMaskPortrait;
}
2nd ViewController code is:
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
-(BOOL)shouldAutorotate
{
return YES;
}
// Tell the system which initial orientation we want to have
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
What i inspect is 'shouldAutorotate' method is not called for 1st and 2nd ViewController.
Your quick help will highly be appreciable.
Thanks.
Kashif

Try to set supportedInterfaceOrientations for 2nd UIViewController like this:
- (BOOL) shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight; // add any other you want
}
Also, enable only portrait in same method in 1st UIViewController.
Maybe you need to enable those orientations also in project settings which 2nd UIViewController needs to support.
[edit #1: Added sample application]
Here you go sample application which solves your problem, hopefully.
AppDelegate.h
#import <UIKit/UIKit.h>
#class FirstViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) FirstViewController *viewController;
#end
AppDelegate.m
#import "AppDelegate.h"
#import "FirstViewController.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.viewController = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
#end
FirstViewController.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController
- (IBAction)goToSecondViewController:(id)sender;
#end
FirstViewController.m
#import "FirstViewController.h"
#import "SecondViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationMaskPortrait;
}
- (IBAction)goToSecondViewController:(id)sender
{
SecondViewController *svc = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self presentViewController:svc animated:NO completion:nil];
}
#end
SecondViewController.h
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController
- (IBAction)goToFirstViewController:(id)sender;
#end
SecondViewController.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
-(BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
- (IBAction)goToFirstViewController:(id)sender
{
[self dismissViewControllerAnimated:NO completion:nil];
}
#end
FirstViewController.xib
SecondViewController.xib

As per your description , first view controller pushed into navigation controller. Your method definition of shouldAutorotate and supportedInterfaceOrientations are absolutely correct. During orientation changes, your navigation Controller's shouldRotate only fired and won't fired your first view controller's(child of nav controller) shouldAutorotate. So you have to category navigationController in your view controller or in seperate file and import into it wherever needed. Code as below for UINavigation Controller category.
.h file have this code
#interface UINavigationController (autoRotate)
-(BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;
#end
.m file have this code
#import "UINavigationController+autoRotate.h"
#implementation UINavigationController (autoRotate)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
If you write category in separate file, you have to import .h file in your first and second view controllers as #import "UINavigationController+autoRotate"

a simple solution:
implement : - (NSUInteger)supportedInterfaceOrientations
when asked from AppDelegate.m
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
for more detail already answered here:
iOS 6 landscape and portrait orientation

Related

How to autoload the first click of a button in iOS?

I have a button created using the .xib file. I want the app to autoload the first question (meaning the ViewController to autoload the "showQuestion" method when the app first started. I am a beginner. How do you do it? Please help! Thanks!
ViewController.m
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
//call the init method implemented by the superclass
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
self.questions = #[#"What is your name?",
#"How old are you?",
#"Where are you from?"];
return self;
}
- (IBAction)showQuestion:(id)sender{
self.questionLabel.text = self.questions[currentIndex];
}
the AppDelegate.m file
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
ViewController *vc = [[ViewController alloc] init];
self.window.rootViewController = vc;
return YES;
}
In your -viewDidLoad method of the view controller, just manually call the -showQuestion method.
i.e. in your ViewController.m, add this:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self showQuestion:nil];
}
Try like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
ViewController *vc = [[ViewController alloc] init];
self.window.rootViewController = vc;
// Autoload first question
[vc showQuestion:nil];
return YES;
}
ViewController.h
- (IBAction)showQuestion:(id)sender;

how to add a navigation controller to a view that is not the main view?

im a beginner and trying to figure out how to work with nib properly.
I have a HomeViewController.h:
#import <UIKit/UIKit.h>
#import "StackTableViewController.h"
#interface HomeViewController : UIViewController
#property (strong, nonatomic) StackTableViewController *stackViewController;
- (IBAction)goToStack:(id)sender;
#end
HomeViewController.m:
#import "HomeViewController.h"
#interface HomeViewController ()
#end
#implementation HomeViewController
- (id)init {
self = [super initWithNibName:#"HomeViewController" bundle:nil];
if (self) {
//
_stackViewController = [[StackTableViewController alloc]init];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)goToStack:(id)sender {
//[self.navigationController showViewController:_stackViewController sender:self];
[self presentViewController:_stackViewController animated:YES completion:nil];
}
As you can see I'm modelling from the HomeViewController to StackTableViewController...
Now it works ok, but I want that StackTableViewController will be embedded in NavigationController...that I can put a cancel button in the top.
This is my StackTableViewController.m:
#import "StackTableViewController.h"
#interface StackTableViewController ()
#property (strong, nonatomic) UINavigationController *navBar;
#end
#implementation StackTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete method implementation.
// Return the number of rows in the section.
return 0;
}
What should I add to the viewDidLoad method that will embed the navBar in the tableview?
tnx
There is not need to declare StackTableViewController as a property of HomeViewController, just modify goToStack like so:
- (IBAction)goToStack:(id)sender {
StackTableViewController *stackViewController = [[StackTableViewController alloc] init]; // shouldnt this get loaded from a NIB though???
[self presentViewController:stackViewController animated:YES completion:nil];
}
About youer issue with UINavigationController, depending on your setup the UINavigationController is the base for a certain navigation stack within your app, so, if you're just building a simple app without a tab bar or another more complex interface, your UINavigationController might be the rootViewController of your application's main UIWindow (a property of your AppDelegate).
So, what you will have to do to get this setup to work is in application:didFinishLaunchinWithOptions of your AppDelegate, set the application's root window:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
HomeViewController *homeViewController = [[HomeViewController alloc] initWithNibName:#"HomeViewController" bundle:nil]; // I assume you have a NIB file called HomeViewController
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:homeViewController];
self.window.rootViewController = navigationController;
return YES;
}
This will have the effect that the HomeViewController that you will see on application startup, is embedded within an instance of UINavigationController, which again is the rootViewController of your whole application.
Then again, you can modify goToStack to use this instance of UINavigationController instead of showing stackViewController modally:
- (IBAction)goToStack:(id)sender {
StackTableViewController *stackViewController = [[StackTableViewController alloc] init]; // shouldnt this get loaded from a NIB though???
[self.navigationController pushViewController:stackViewController animated:YES];
}
You can use self.navigationController here because homeViewController is embedded in a UINavigaitonController, so iOS will set this property for you.
Hope that helps! :)
Update:
If you don't want to have your HomeViewController embedded within the UINavigationController, just modify goToStack like so:
- (IBAction)goToStack:(id)sender {
StackTableViewController *stackViewController = [[StackTableViewController alloc] init]; // shouldnt this get loaded from a NIB though???
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:stackViewController];
[self presentViewController:navigationController animated:YES completion:nil];
}

root view controller when upgrading app to ios 6 [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
XCode 4.5.1, Application windows are expected to have a root view controller at the end of application launch
I'm a total noob in IOS app developing.
I use Xcode 4.5.1 with no storyboard.
I'm upgrading an IOS 4 app because it fails to run correctly on IOS 6 devices.
main view containing a question and five answers run once and stops there after user commit by pressing a button with the wanted answer, it should then reload itself with a new question and a new set of questions.
I get the infamous "Application windows are expected to have a root view controller at the end of application launch" in log output.
I've read and tried all comments and solutions in 7520971 but to no avail... still getting error and it seems to prevent me to load the view correctly.
here's what in my appDelegate.h
/*
* AnimViewAppDelegate.h
* AnimView
*
* Created by Administrateur local on 11-01-19.
* Copyright 2011 __MyCompanyName__. All rights reserved.
*
*/
#import <UIKit/UIKit.h>
#import "RootNavigationController.h"
#interface PPScaleAppDelegate : NSObject <UIScrollViewDelegate> {
UIWindow *window;
RootNavigationController *RootNavigationViewController;
}
#property (nonatomic, retain) UIWindow *window;
#property (nonatomic, retain) RootNavigationController *RootNavigationViewController;
#end
my appDelegate.m
//
// AnimViewAppDelegate.m
// AnimView
//
// Created by Administrateur local on 11-01-19.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "PPScaleAppDelegate.h"
#import "QuestionView.h"
#implementation PPScaleAppDelegate
#synthesize window;
#synthesize RootNavigationViewController;
//- (void)applicationDidFinishLaunching:(UIApplication *)application {
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Create the main screen
//CGRect frame = [[UIScreen mainScreen] bounds];
//self.window = [[UIWindow alloc] initWithFrame:frame];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; //2012
//Create the main view controller
RootNavigationViewController = [[RootNavigationController alloc] initWithNibName:NULL bundle:NULL];
//[window addSubview:RootNavigationViewController.view];
[self.window setRootViewController:RootNavigationViewController];
//Show the main window
[self.window makeKeyAndVisible];
return YES;
}
- (void)dealloc {
[window release];
[super dealloc];
}
#end
.h
//
// RootNavigationController.h
// IPhonePPS
//
// Created by Administrateur local on 11-02-11.
// Copyright 2011 Le Groupe CDGI Inc. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "QuestionView.h"
#import "ResultView.h"
#import "ResultTableView.h"
#interface RootNavigationController : UINavigationController {
QuestionView *QuestionViewController;
ResultView *ResultViewController;
ResultTableView *ResultTableViewController;
}
#property(nonatomic, assign) QuestionView *QuestionViewController;
#property(nonatomic, assign) ResultView *ResultViewController;
#property(nonatomic, assign) ResultTableView *ResultTableViewController;
-(void)switchToResultMode:(QuestionPath *)QuestionPath;
-(void)switchToResultTableMode;
-(void)switchBack:(BOOL)Reset;
#end
.m
//
// RootNavigationController.m
// IPhonePPS
//
// Created by Administrateur local on 11-02-11.
// Copyright 2011 Le Groupe CDGI Inc. All rights reserved.
//
#import "RootNavigationController.h"
#implementation RootNavigationController
#synthesize QuestionViewController, ResultViewController, ResultTableViewController;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Initialization code.
QuestionViewController = [[QuestionView alloc] initWithNibName:NULL bundle:NULL];
ResultViewController = [[ResultView alloc] initWithNibName:NULL bundle:NULL];
ResultTableViewController = [[ResultTableView alloc] initWithNibName:NULL bundle:NULL];
//Set the navigation bar hidden
[self setNavigationBarHidden:YES];
//Push the question view on the stack
[self pushViewController:self.QuestionViewController animated:YES];
}
return self;
}
- (void)dealloc {
[super dealloc];
}
-(void)switchToResultMode:(QuestionPath *)QuestionPath {
[self pushViewController:ResultViewController animated:YES];
[ResultViewController setQuestionPath:QuestionPath];
}
-(void)switchToResultTableMode {
[self pushViewController:ResultTableViewController animated:YES];
}
-(void)switchBack:(BOOL)Reset{
if(Reset){
if([self.viewControllers count] == 3){
[self popToRootViewControllerAnimated:YES];
}else {
[self popViewControllerAnimated:YES];
}
[QuestionViewController resetAnswers];
}else {
[self popViewControllerAnimated:YES];
}
}
//-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
// if([self visibleViewController] == self.ResultTableViewController || toInterfaceOrientation == UIInterfaceOrientationPortrait){
// return YES;
// }else {
// return NO;
// }
//}
- (BOOL) shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
#end
spent two complete days trying to debug this but I give up and would really appreciate your help with this issue
PR
It would be better to just use [[alloc] init] if you don't have a nib for your navigation controller. Also, your navigation controller should be initialized with its own rootViewcontroller. I don't know which one you want to be first, but it should look something like this:
MyFirstViewControllerClass *rootVC = [MyFirstViewControllerClass alloc] initWithNibName:#"MyFirstViewController" bundle:nil];
RootNavigationController *nav = [[RootNavigationController alloc]initWithRootViewController:rootVC];
self.window.rootViewController = nav;
You're calling [self.window setRootViewController:RootNavigationViewController]; Notice - setRootViewController. It wants a viewController. Your RootNavigationViewController is a NavigationController as referenced here #interface RootNavigationController : UINavigationController not a viewController.
It looks like you should do something like this
RootNavigationViewController = [[RootNavigationController alloc] initWithNibName:NULL bundle:NULL];
[window makeKeyAndVisible];
[window addSubview:RootNavigationViewController.view];
(referenced from Programmatically build / navigate a Navigation Controller)
I'm not sure if using
[self pushViewController:self.QuestionViewController animated:YES];
in the RootNavigationViewController is the same as doing something like this
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
But that should point you in a good direction to debug your issue.
You should init your RootNavigationController with a rootViewController first :
[RootNavigationController initWithRootViewcontroller:QuestionViewController];
You can find this from the UINavigationController reference :
Because the UINavigationController class inherits from the
UIViewController class, navigation controllers have their own view
that is accessible through the view property. When deploying a
navigation interface, you must install this view as the root of
whatever view hierarchy you are creating.
For instance, in -(void)switchBack:(BOOL)Reset; you popToRootViewController without even having set it.

Xcode 4 for Dummies: Why are Storyboard Settings not Being Applied When the App Runs?

SOLUTION
Make sure in the plist that the storyboard name is listed as the main storyboard file name.
I have a Storyboard with a UINavigationViewController that's connected to a NavigationViewController class and it's set as the UIWindow rootViewController. When the app runs (in the Simulator (5.1)) I get a blank black screen with the blue-ish navigation bar on the top.
The first problem is that in the storyboard, I set the navigation bar to black. I also set the status bar to translucent black. Neither styles are being honored when the app runs.
And the second problem is that the navigation controller's view is empty even though in the storyboard it has a relationship to a UITableViewController.
How can I fix both of these issues. I just started using Xcode again and had been using 4.0 before so the storyboards are throwing me off...
UPDATE
Here's the code as requested. Obviously I can't post the storyboard (can I?).
AppDelegate:
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
navigationController = [[NavigationViewController alloc] init];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
#end
NavigationViewController:
#import "NavigationViewController.h"
#interface NavigationViewController ()
#end
#implementation NavigationViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
The problem is that you are setting as the root controller a completely blank root controller, not the one from the story board. What you want to do is to delete that part of the code, and simply on the storyboard click the thing that says "is initial view controller"
When using storyboards you usually dont have to modify the appdelegate, because xcode sets which is the initial view that will appear and all of that based solely on how you set the storyboard. You can check this in the plist where it says which storyboard will be used as the main one.
If you want to load your navigation controller like that then you can do something like that you would have to get the viewcontroller from the storyboard itself and present it.
instantiateViewControllerWithIdentifier
but there is no need for that when using storyboards as it automatically loads whichever is set as the initial one (which can be seen as the viewcontroller with the arrow pointing at it)
Your app delegate method should look like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}

Clicking a button results in exe_bad_action

I created a brand new project and created a new view controller with a button in the view.
I am adding the view in application:didFinishLaunchingWithOptions
- (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];
BOOL introDisplayed = [[NSUserDefaults standardUserDefaults] boolForKey:kIntroScreenSeenByUser];
if(introDisplayed)
{
}
else
{
IntroView *introView = [[IntroView alloc] initWithNibName:#"IntroView" bundle:nil];
[self.window addSubview:introView.view];
}
[self.window makeKeyAndVisible];
return YES;
}
.h file
#interface IntroView : UIViewController
#property (weak, nonatomic) IBOutlet UIButton *clickMe;
- (IBAction)clicked:(id)sender;
#end
.m file
#import "IntroView.h"
#interface IntroView ()
#end
#implementation IntroView
#synthesize clickMe;
- (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 from its nib.
}
- (void)viewDidUnload
{
[self setClickMe:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)clicked:(id)sender {
NSLog(#"clicked");
}
#end
Clicking on the button results in a EXC_BAD_ACCESS(code=2 error. Any ideas? I am using ARC.
Thanks
UPDATE
Created a public property on the application delegate called "introViewController" and changed the application:didFinishLaunchingWithOptions
#synthesize introViewController;
- (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];
BOOL introDisplayed = [[NSUserDefaults standardUserDefaults] boolForKey:kIntroScreenSeenByUser];
introViewController = [[IntroView alloc] initWithNibName:#"IntroView" bundle:nil];
if(introDisplayed)
{
}
else
{
[self.window addSubview:introViewController.view];
}
[self.window makeKeyAndVisible];
return YES;
}
This solved the error.
You're creating your IntroView controller, and adding it's view as a subview, but the controller itself is released. I don't think that adding the view controller's view (and then letting ARC discard the controller itself) is an acceptable way to create a view.
Perhaps you could make the IntroView view controller a property of the app delegate class and therefore it won't be released by ARC.
Personally, I don't monkey around with the app delegate's creation of the views and controllers, but rather I let my target settings and my NIBs dictate that. I presume you're doing this because you want to have some intro screen. If I wanted an screen, I'd have my main view controller go ahead and present whatever intro I want. That way when the intro is dismissed (or popped off, depending upon whether you pushed or presented modally), my main view controller is still at the top (and useful methods like popToRootViewController work perfectly).

Resources