Orientation problem - objective-c

i have created and ipad application.
i started off with window based application and added 2 view controllers(loginviewcontroller , detailviewcontroler ) . both have their own XIB'S. the added the loginviewcontroller object in in the appdelegate applicationdidfinishlaunch method , i wrote code to move back and forth between 2 views. Here is the code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
Login *mylogin = [[Loginviewcontroller alloc] init];
[window addSubview:mylogin.view];
//detailview *tv=[[detailviewcontroller alloc] init];
// [window addSubview:tv.view];
[self.window makeKeyAndVisible];
return YES;
}
The problem is that the willrotatetointerfaceorientation method runs only from the loginviewcontroller class even if i am in the detailviewcontroller.
if i add the tickets view to the appdelegate then it runs the willrotatetointerfaceorientation method from detailviewcontroller , so in summary it runs the willrotatetointerfaceorientation method from only the object which was added to appdelegate.
how do i make the 2 view controllers run their respective willrotatetointerfaceorientation methods?

UIViewController has the method
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
override this method in your both viewcontroller classes(i.e. (loginviewcontroller , detailviewcontroler )
write this code
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//write your code which you want to during rotation
return Yes;
}

The rotation messages are being sent only to the controller of topmost view. You should forward them manually in appropriate methods.

Related

self.navigationController == nil after awaking from LocalNotification

I'm working in Xcode 4.3.2
I implemented Local Notifications that alert the user of a new event at a predetermined time. So when my app is in the background and the clock strikes 8 am (for instance), the user will get a notification from my app.
When the user decides to view the app from the background I load a nib. Currently, this nib works properly: it shows the view as it was it arranged in the nib. However, after the nib is shown to the user, I want to forward the user to a different view in the LocalNotificationsHandler.m. When I attempt to push the second view, my app fails. So while there isn't an error message, it seems the second nib will not load.
In short the flow goes as follows:
user gets notification while my app is running in the background
user chooses to view the app
the LocalNotificationsHandler nib will load
self.navigationController == nil (in LocalNotificationsHandler.m)
self.navigationController will not "[pushViewController: "new view" animated:YES]" to get a new view
I'm wondering if there is something I'm missing from my AppDelegate.m file so I've included
"didFinishLaunchingWithOptions" from my AppDelegate.m file:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// Add the navigation controller's view to the window and display.
NSLog(#"did finish launching with options");
[self.window addSubview:tabBarController.view];
[self.window makeKeyAndVisible];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
if (self.locationManager == nil)
{
locationManager = [[CLLocationManager alloc] init];
locationManager.purpose = #"We will try to use you location";
}
if([CLLocationManager locationServicesEnabled])
{
[self.locationManager startUpdatingLocation];
}
self.navigationController.navigationBar.tintColor = nil;
return YES;
}
You are using the outdated (since iOS 3) method of adding the viewcontroller's view to the main UIWindow. That should be looking like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// create properly sized window
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// create instance of root VC and assign to window
MainViewController *vc = [[MainViewController alloc] init];
self.window.rootViewController = vc;
[vc release];
[self.window makeKeyAndVisible];
return YES;
}
The navigationController property of a view controller is ONLY set if it is actually presented from a UINavigationController.
See this writeup for more information: http://www.cocoanetics.com/2012/11/revisited/

How do I know the window of my view?

ViewWillAppear is never called automatically I have to call them manually. ViewWillDisappear is often called though.
I do not know where to debug this.
I suppose the problem is because I created the application on 4.1 where people have to call viewWillAppear explicitly.
I suppose, because viewWillAppear will be called depending on its relation with window I can check if my viewController has an outlet to window.
How do I do so?
I suspected the problem is somewhere in my delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[Crashlytics startWithAPIKey:#"a08863b514ef09558ba82fec070cc7468fdbeeae"];
if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
{
NSLog(#"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");
}
[self.window addSubview:self.navController.view]; //This seem to be the problem. I should have specified the viewController and not the view
[self.navController pushViewController:self.MainBadgerApplication animated:YES];
//[cachedProperties singleton].lastAnchor =[cachedProperties currentLocation];
[cachedProperties singleton].currentAnchor=[cachedProperties currentLocation];
self.MainBadgerApplication.selectedIndex=0;
[BNUtilitiesQuick tabBarController:self.MainBadgerApplication didSelectViewController:self.MainBadgerApplication.selectedViewController];
[self.window makeKeyAndVisible];
return YES;
}
I suspected that
[self.window addSubview:self.navController.view]; is the issue.
Also I've heard before ios5 you do have to call viewController explicitly. So should I create a different program for ios5 and ios4 (not like there is any danger in calling viewController twice for my program)
I suspected that [self.window addSubview:self.navController.view]; is the issue.
Probably. You should be doing this instead:
self.window.rootViewController = self.navController;
Just adding the view doesn't put your view controller into the hierarchy properly. See the WWDC 2011 view controller containment video for more information.

Correct pattern for refreshing data in UIViewController's

I am trying to refresh my view data when the application becomes the active app again. I believe the correct pattern is to have the app delegate tell it's view to reload it's data when applicationDidBecomeActive is called.
However, I am having trouble finding the UIViewController from within the Delegate:
- (void)applicationDidBecomeActive:(UIApplication *)application {
MyFancyViewController* controller = //how do I get my view controller???
[controller refreshData];
}
Also, can I count on the view controller still being allocated, or is there a chance it would go away? I'm using iOS 5 Storyboard's if that makes any difference.
Update:
I think I got it:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
UIViewController* root = _window.rootViewController;
UINavigationController* navController = (UINavigationController*)root;
OctainViewController* mycontroller = (OctainViewController*)[[navController viewControllers] objectAtIndex:0];
[mycontroller refresh:nil];
}
Yeah, this does the trick:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
UIViewController* root = _window.rootViewController;
UINavigationController* navController = (UINavigationController*)root;
OctainViewController* mycontroller = (OctainViewController*)[[navController viewControllers] objectAtIndex:0];
[mycontroller refresh:nil];
}
Why not refresh your data in the respective view controller viewWillAppear method?

How to configure app so that root view controller is found?

I am new and am working on an exercise which involves starting with a navigation-based template. Since I am running Xcode 4.2 which no longer has that template, I have started with an empty application template, and then copied the directory structure of the completed app.
Since the empty app template starts only with an AppDelegate.h, .m files, I started adding other required files, including the MainWindow.xib, and the RootViewController.h, .m files. Did some tweaking of the #import directive so that it could see the right files, and could start alright.
However, when I try to run it on the iOS Simulator, I got this message: Applications are expected to have a root view controller at the end of application launch
Terminating in response to SpringBoard's termination.
Program ended with exit code: 0
What additional changes do I need to make so that the app can see the RootViewController?
Thank you.
In -[AppDelegate application:didFinishLaunchingWithOptions:], you need to set your window's rootViewController property.
You need to set the rootViewController property of AppDelegate's _window:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
_window.rootViewController = self.myNavigationController;
[_window makeKeyAndVisible];
return YES;
}
To start a traditional navigation-based project in XCode 4.2, I find it easier to start with the single-view template. Then, in AppDelegate, I substitute the generated UIViewController with a UINavigationController.
self.window.rootViewController=self.yourviewControollerobj
You can set like this. First set the window bounds then add you navigation controller with root view controller.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
MainViewController *vc = [MainViewController new];
/*
* If you are using .xib you should create UIViewontroller like this
* MainViewController *vc = [MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil]
*/
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
[self.window setRootViewController:self.nc];
[self.window makeKeyAndVisible];
return YES;
}
MyViewController *rootCtr = [[MyViewController alloc] init];
[rootCtr.view addSubview:myView];
window.rootViewController = rootCtr;

UINavigationController, simply hiding the navigation bar

I've I have a simple noob question, I would like to hide the navigation bar of a UINavigationController, but I'm pretty sure I`m not calling the right object .
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIViewController *rootViewController = [[[TestViewController alloc] init] autorelease];
viewController = [ [UINavigationController alloc] initWithRootViewController:rootViewController];
[window addSubview:viewController.view];
[window addSubview: rootViewController.view];
[window makeKeyAndVisible];
return YES;
}
Now, I`ve tried, this :
-(void)hideBar {
viewController.navigationBarHidden = YES;
}
It is complaining that "navigationBarHidden" not found on object type UIViewController, obviously I would need to call the UINavigation controller instead, but that's where I'm stuck ...
Try:
[self.navigationController setNavigationBarHidden:YES];
within your TestViewController. A good place is in viewDidLoad
Also, while we're at it, remove the line [window addSubview:rootViewController.view];, you don't need it.
In Navigation controller's root view controller's method viewDidLoad write this -
[self.navigationController setNavigationBarHidden:TRUE];
in your case its TestViewController.