Setting root view controller in didReceiveLocalNotification: results in black window - objective-c

I know different versions of this question has been asked before but I'm really stuck here. I'm trying to get my app to push a new view from my app delegate when getting:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)localNotif {
And I put the following code in there:
MyViewController *myViewController = [[MyViewController alloc]init];
nvcontrol = [[UINavigationController alloc] initWithRootViewController:myViewController];
[nvcontrol.navigationBar setTintColor:[UIColor blackColor]];
self.window.rootViewController = nvcontrol;
and from this, I get a black view (which myViewController should not have) with a black navigation bar.
What am I doing wrong here?

As I've outlined above, you can use storyboard to set the initial view controller.
Note that if you have a view controller set up in storyboard and then you create a view controller in the application delegate, the view controller you created won't look like your one in storyboard. This is because you are making an instance of the CLASS, but the program has no way to associate this with your layout.

Related

how to change current displaying uiview without using segues?

i want to change display to an UIViewController which has view controller at storyboard from an UIViewController class which hasn't got view controller at storyboard. There is no segue at storyboard for this...
Just like this:
In your AppDelegate.m do a quick setup:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
ViewController *sourceViewController = [[ViewController alloc] init];
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:sourceViewController];
[self.window setRootViewController:nav];
return YES;
}
In above example replace ViewController class with your own class of sourceViewCntroller
- (IBAction) didPressMyButton {
NewViewController* newVC = [[[NewViewController alloc] init] autorelease];
[self.navigationController pushViewController:newVC animated:YES];
}
Connect this action to a button on storyboard or embed view change in any method. You will need to setup UINavigation controller first.
I'm not completely sure I understand what you're trying to do, but I think you are asking how to load a view controller from a storyboard, without using a segue, from a method in a view controller that wasn't loaded from the storyboard.
First, in your storyboard, select the view controller you want to load, and open the Identity Inspector. Set the Storyboard ID of the view controller. It looks like you want to load a MapViewController, so let's say you set the storyboard ID to map.
In your code, you can load the view controller like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
MapViewController *mapViewController = [storyboard instantiateViewControllerWithIdentifier:#"map"];
Once you have a reference to the view controller, you can set its properties or send it messages. You can then display it in whatever way you want - maybe by pushing it onto a navigation controller, or by presenting it, or by setting it as the root view controller of your window.

Switch views - UIViewController to UITabBarController

I have made a very simple Navigation based app (UIViewController). The view has a single button on the Main RootViewController.
Next, I made 2 classes: TabOneViewController, TabTwoViewController. All good. I then created a new Class TabBarViewController. I opened up the NIB file and dropped on a ``UITabBarController onto it. The two tabs it creates in it by default were assigned (respectively) to my TabOne and TabTwo view controllers.
strong text
Then in my TabBarViewController, I made an IBOutlet for a UITabBarController, synthesized it etc etc. I linked it up in Interface builder via the "files owner".
In the RootViewController, I linked the button to my "pushView" method, and in this pushView method, I have the following code:
- (IBAction) pushView {
TabBarViewController *controller = [[TabBarViewController alloc] init];
[self.navigationController pushViewController:controller animated:YES];
[controller release];
}
The end result is it DOES push a view, but I cannot see the tab bar at the bottom, let alone any of the pages I've added to the controller.
What am I doing wrong? Why can't I link it in IB?
I am not 100% sure if that's allowed.. because you already have one tabBarController as rootViewController, and you dropped one more tabBarController as first tab controller, tabs ll overlap, considering amount of real estate you have on your iPhone, it make sense to not allow a tabViewController inside another
First, you need to allocate your view controller with your nib:
TabBarViewController *controller = [[TabBarViewController alloc] initWithNibName:#"YourNibName" bundle:nil];
Secondly, in IB, click the UITabBarController and go to the identity inspector and make sure you select your custom class. That said, unless you are overriding or adding some functionality you probably don't need the custom class at all, simply use a UITabBarController directly:
UITabBarController *controller = [[UITabBarController alloc] initWithNibName:#"YourNibName" bundle:nil];

Setting up and using the UINavigationController class in Objective-C

I am trying to use the UINavigationController class in Objective-C, but I am having a difficult time understanding how it should work.
Basically, I have my app. I want to use the UINavigationController to show a hierarchy of data stored in an NSArray. I currently have this data being presented in UITableView. I want to make it so a user can click on a row of the table view and be taken to more specific data about the row they just clicked. I think a UINavigationController is perfect for this.
However, my understanding of MVC in the context of Objective-C is not that good and I am confused about how to do this. I want the UINavigationController to only show up in the left half of my iPad app and I would also like the ability to hide it at times. So how do I configure this?
This sounds like the correct usage for a navigation controller.
What you will need to do is create your navigation controller and populate the root view with your view controller containing the table view. In your didSelectRowAtIndexPath you would push the detail view onto the stack. All the navigation will be set up to go back for you.
Most likely in your AppDelegate:
ListViewController *theView = [[ListViewController alloc] initWithNibName:#"ListViewController" bundle:nil];
UINavigationController *navView = [[UINavigationController alloc] initWithRootViewController:theView];
[theView release];
[window addSubview:navView.view];
[window makeKeyAndVisible];

How to replace RootViewController in "Navigation-based application"

I have an application that uses the "navigation-based application" template in XCode.
Now I want to change it so that the first view that loads is a regular (custom) UIView, and if the user clicks a particular button, I push the original RootViewController onto the NavigationController.
I understand that somewhere, someone is calling this with my RootViewController:
- (id)initWithRootViewController:(UIViewController *)rootViewController
I want to know how to replace the argument with my new class.
if you want to replace the root view controller of your navigation stack you can replace the first object of its view controllers array as -
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[self.navigationController viewControllers]];
NewViewController *nvc = [[NewViewController alloc] init];
[viewControllers replaceObjectAtIndex:0 withObject:nvc];
[self.navigationController setViewControllers:viewControllers];
^ These are all ways to do it programmatically. Thats cool. But I use the interface builder and storyboards in Xcode, so this is the easy and fast way to add a new view controller:
Open the storyboard in question
Add a new view controller to your storyboard by dragging it from the objects list (right hand tool bar bottom)
While holding down the CONTROL key, click and drag from the middle of your navigation controller (should be blank and gray) to your new fresh white view.
On the popup, selection Relation Segue: Root View Controller (should be below the normal push/modal/custom options you have likely seen before)
Tada! Enjoy your new root view controller without holding your day up with programmatic creation.
Look inside the main app delegate .m file and find the method
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Inside it will be a line like this
self.window.rootViewController = self.navigationController;
You can instantiate a diffent view controller there and assign it to be the rootViewController

Create UINavigationController programmatically

Just because I am unable to find a secure way (in a sense that it can be rejected by Apple guys) to customize UITabbar, in particular UITabBarItem I am trying some workaround.
I have a main view on which I recreate a kind of UITabBar, a normal view with two buttons inside. This is (roughly) the current hierarchy:
-MainView
--placeholder(UIView)
--fakeTab (UIView)
What I want to do is, after tapping a button in fakeTab, build a UINavigationController and add it to "placeholder" view so that the fakeTab remain on top and the whole navigation happens on the placeholder level.
I already tried with this piece of code in the method that it's intercepting tap button, and it works, I can see the ipvc.view added to placeholder.
IPPlantsViewController *ipvc = [[IPPlantsViewController alloc] initWithNibName:#"IPPlantsView" bundle:[NSBundle mainBundle]];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:ipvc];
UIView *placeholder = [self.view viewWithTag:200];
[placeholder addSubview:ipvc.view];
But later when I call from inside ipvc, then nothing happens:
IPAttributes *ipas = [[IPFactory findPlantByIndex:indexPath.row] attrs];
[self.navigationController pushViewController:ipa animated:YES];
I find the solution myself. What I was doing wrong is to attach the ipvc controller view to placeholder. Instead of doing this:
[placeholder addSubview:nav.view];
and everything works as expected, with my fake tabbar fully customized :-)
But, as a side note, the viewWillAppear seems to be never called.
It would be interesting to know why. I partially solved by making IPPlantsViewController the delegate of the UINavigationController.