Navigation items for navigation controller in interface builder - objective-c

- i have a FirstViewController and a SecondViewController, each has its xib
- in the MainWindow.xib i have a UINavigationController, which is connected to IBOutlet
- in the AppsDelegate i call
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
FirstViewController * fv = [[FirstViewController alloc] init];
[navigationController pushViewController:fv animated:NO];
[fv release];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
4) the problem is, when i want to manage Navigation item through interface builder... like for the first view i want to add a button to the right and customize the back text and the title
sure i could do this using code :
(by fv.navigationItem.rightBarButtonItem = ... and fv.title=#"...") but i want to achive this in interface builder
in my FirstViewController.xib and SecondViewController.xib i add a Navigation item and add the a right Bar item
the problem is, it never shows up and the title doesnt alter
if i open MainWindow.xib and add a ViewController (FirstViewController) under the NavigationController (so its listed under it = make it the rootViewController for the NavigationController) and also add Navigation item and Bar Buttom item, whoala, the NavigationBar at the top has the left button
again this would be great... BUT i cannot do the same think for the SecondViewController, because in interface builder, there can be only one rootViewController under the Navigation Controller... and again if i add the Navigation item in SecondViewController.xib it doesnt show up:(
- so ho can i manage the Navigation items and Bar button items for multiple ViewControllers in interface builder
(i looked at most tutorial, but they do it inside the code, by .navigationItem.rightBarButtonItem, what i want to avoid)

ok, the best solution i found
is to design the buttons in Interface builder and link them via Outlet, then in code i simply add them
fv.navigationItem.rightBarButtonItem = myOutletButton;
i didnt find a way to do it just only in interface builder so it gets bind automaticly :(

If u like to do a separate NVC please instaniate it not from main view, do this from different view's separate.

Related

How to specify the left, right, or title View button in XIB

I do not want to create a custom navigation bar.
I am pushing a UIViewController and I want to customize how the navigation bar looks for that UIViewController
In story board, we just specify the segue and a nav bar show up on the screen. We just drag and drop UIBarItem to the left and right.
In XIB, the navigationBar simply doesn't show up.
I can add navigation Item but the one I added is ignored.
I've heard that there used to be an outlet called navigationItem but it's deprecated for reason I do not know.
I can add UINavigationBar, however that would be adding my own custom bar. I want the navBar that's provided by UINavigationController.
The appearance of the Navigation Bar in the storyboard designer is just there to illustrate how your screen will look when you load your ViewController inside a UINavigationController. It doesn't mean that you actually have a navigation controller in your app.
You need to add a UINavigationController to your storyboard (probably as the first scene), and then connect your ViewController to it (as the root view controller).
Then you should be able to set your title in the storyboard designer, and drag bar button items onto the navigation bar.
See also the answer to this question.
You can setup it in code.
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Title";
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back"style:UIBarButtonItemStyleBordered target:self action:nil];
self.navigationItem.rightBarButtonItem = "Create button" ;
self.navigationItem.leftBarButtonItem = "Create button" ;
self.navigationItem.titleView = "Create custom title view";
}
I think this is the actual way apple want this to be implemented.
Put UINavigationBar
Set outlet to the UINavigationItem
This is the catch
Override navigationItem property to return the UINavigationItem you created.
That's it.
-(UINavigationItem *) navigationItem
{
return self.navigationItem1;
}
If your navigationItem is still in the UINavigationBar, I think you will need to have a strong outlet to the UINavigation Bar too. Please correct me if I am wrong here.

tabbar issue with navigation controller

I am trying to find a way to avoid this but doesn t seem to find it anywhere
I have a tabbar application in Storyboard
inside one of the tabs I have a navigation bar that goes up to three views in a row
if I go to the third view then switch tabs and come back to the same tabs I see the third view and not the first one ... any way to solve this ?
Thanks
implement the below delegate of tab bar in your appDelegate class, dont forget to set delegate of tab bar to your appDelegate or the class in which tab bar is present.
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
[(UINavigationController*)self.tabBarController.selectedViewController popToRootViewControllerAnimated:NO];
return YES;
}
if you are using story board, write the below code in your didFinishLaunching method of your appDelegate, then your delegate method will be called.
UITabBarController* tab = (UITabBarController*)self.window.rootViewController;
tab.delegate = self;
this will do your work, let me know if it doesn't work for you.

navigation controller is null when pushing new view

I have a tab bar application and in one of those tabs I have a map view. I am trying to push a new view from clicking a disclosure button on an annotation on the map view using this code...
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
childController = [[AnnotationDetailView alloc] initWithNibName:#"AnnotationDetailView" bundle:nil];
[self.navigationController pushViewController:childController animated:YES];
}
however if I nslog the navigationController it is null.
What is confusing is that in another tab I have a table view which will push a view using the above code. Why does that work but an map annotation doesn't.
The simple answer is that your table view is inside a navigation controller and your map view isn't. A tab view controller isn't actually a navigation controller itself.
Depending on your project, the fix may be as simple as editing your XIB so that a navigation controller is the immediate child of the tab controller for the map's tab, and the map view controller is the child of that navigation controller. Look at how your table view is defined, and you should be able to see what's different.
Have you defined childController as AnnotationDetailView * childController; in your header?
or you can simply use:
AnnotationDetailView * childController = [[AnnotationDetailView alloc] initWithNibName:#"AnnotationDetailView" bundle:nil];

iOS: UITabBarController - lazy loading of item views

I have read that subclassing a UITabBarController is a non-recommended practice. However, how then is possible to implement lazy loading of the views of tab bar items?
I'm playing around with a standard app view hierarchy: In my main app delegate file (application:didFinishLaunchingWithOptions:) , I'm instantiating a custom subclass of UITabBarController with a 4 tab bar items / icons. I only need to load the first view of the first tab bar item - other views should be loaded lazily upon request. So, in application:didFinishLaunchingWithOptions:, I'm loading welcome view and pushing it into the first UINavigationController(1). The other tab bar items are empty UINavigationControllers - (2, 3, 4). Here is my custom subclass of UITabBarController that is also a delete of himself:
#interface MainUITabBarController : UITabBarController <UITabBarControllerDelegate> {
}
#end
#implementation MainUITabBarController
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{
UIImageView *image = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"TableViewBG.jpg"]] autorelease];
UIViewController *vc = [self.viewControllers objectAtIndex:item.tag];
vc.view = image;
}
#end
Currently, the view of the second tab bar item is just a UIViewController but I it will become a UINavigationController soon :)
So, back to the problem, what other (more apple-complaint) options would be to implement tab bar item action handling for lazy-loading?
If I understand your question correctly, by default TabbarController loads item's view in lazy mode. That is, unless you click on a certain item on tab bar, it won't be loaded.
You can check this by putting log on each view's viewdidload and see when it is getting called.

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