rightBarButtonItem does not appear in Navigation Bar iOS - objective-c

I'm having problems displaying the rightBarButtonItem of the Navigation Bar - I'm attempting to create it programmatically in the Application Delegate, where my UINavigationController is set up.
Code is as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
RSCListViewController *list = [[RSCListViewController alloc] initWithStyle:UITableViewStylePlain];
self.navController = [[UINavigationController alloc] initWithRootViewController:list];
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithTitle:#"+"
style:UIBarButtonItemStylePlain
target:list
action:#selector(addPressed:)];
self.navController.navigationItem.rightBarButtonItem = barButton;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
[DatabaseManager openDatabase];
return YES;
}
Running the application, no button item appears on the navigation bar.
I'm not sure whether I have missed something obvious - my attempts to rectify the problem using related Stack Overflow threads haven't yielded any success.
Any help appreciated.

You need to attach your bar button item to your custom view controller, not to the navigation controller. From Updating the Navigation Bar:
In addition, the navigation controller object builds the contents of
the navigation bar dynamically using the navigation items (instances
of the UINavigationItem class) associated with the view controllers on
the navigation stack. To change the contents of the navigation bar,
you must therefore configure the navigation items for your custom view
controllers.
(...)
The navigation controller updates the right side of the navigation bar
as follows:
If the new top-level view controller has a custom right bar button item, that item is displayed. To specify a custom right bar button
item, set the rightBarButtonItem property of the view controller’s
navigation item.
If no custom right bar button item is specified, the navigation bar displays nothing on the right side of the bar.
Therefore, replace:
self.navController.navigationItem.rightBarButtonItem = barButton;
with:
list.navigationItem.rightBarButtonItem = barButton;

Related

Xcode open specific view with push notifications in storyboard

In my codes, I wrote it in this way
DetailView *vc = (DetailView *)[mainStoryboard instantiateViewControllerWithIdentifier:#"DetailVC"];
self.window.rootViewController = vc;
It only show that view but I don't see the navigational bar and tab bar.
What is the right way to open a specific view (inside tabbarcontroller) within storyboard when the app receive remote notifications automatically?
That's because you get only DetailView from storyboard. If you want to show it inside navigation controller you have to init this controller.
DetailView *vc = (DetailView *)[mainStoryboard instantiateViewControllerWithIdentifier:#"DetailVC"];
UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController: vc];
self.window.rootViewController = navVC;
But I think the issue is in other. You instantiate wrong view controller. You should instantiate tab bar controller or navigation controller and then only select proper tab.

Hide FBFriendPickerViewController navbar when pushing onto UINavigationController

Presenting an instance of FBFriendPickerViewController using presentViewController:animated:completion: is pretty straightforward and the class seems like it is meant for that use case. However, I want to push an instance of FBFriendPickerViewController onto an instance of UINavigationController using pushViewController:animated:.
Consider the following code as an example:
self.fbFriendPickerController = [[FBFriendPickerViewController alloc] init];
self.fbFriendPickerController.hidesBottomBarWhenPushed = YES;
// configure stuff
[[self navigationController] pushViewController:self.fbFriendPickerController animated:YES];
However, the problem is that the instance of FBFriendPickerViewController already has a top navigation bar. When pushed onto a UINavigationController, this results in two top navigation bars stacked vertically, as you can see in the screenshot below.
One solution would be to hide the top nav bar of the UINavigationController, but that creates an awkward transition and there is no back button. Any thoughts on the best way to keep the UINavigationController top nav bar but the hide the FBFriendPickerViewController top nav bar?
After looking through the Facebook iOS SDK source code on Github, I figured this out. FBFriendPickerViewController is a subclass of FBViewController. If you set the doneButton and cancelButton properties of any FBViewController to nil, FBViewController will remove the top navigation bar. As a result, the following code works:
self.fbFriendPickerController = [[FBFriendPickerViewController alloc] init];
self.fbFriendPickerController.hidesBottomBarWhenPushed = YES;
self.fbFriendPickerController.doneButton = nil;
self.fbFriendPickerController.cancelButton = nil;
// configure stuff
[[self navigationController] pushViewController:self.fbFriendPickerController animated:YES];

How to display Kal's calendar in a TabBar Controller's UIVIew?

I am creating an iPad app using XCode 4 and Storyboards. I have a TabBar Controller with two UIViews. I have my iPad app and Kal in a workspace. I am trying to copy some of the Kal sample code to get the calendar to display. This is what I have copied (with minimal changes):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// initialization...
KalViewController *kal = [[KalViewController alloc] init];
kal.title = #"Saori";
// configuration
kal.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Today" style:UIBarButtonItemStyleBordered target:self action:#selector(showAndSelectToday)];
kal.delegate = self;
EventKitDataSource *dataSource = [[EventKitDataSource alloc] init];
kal.dataSource = dataSource;
// Setup the navigation stack and display it.
navController = [[UINavigationController alloc] initWithRootViewController:kal];
[window addSubview:navController.view];
[window makeKeyAndVisible];
return YES;
}
On the last 3 lines (Setup the navigation stack and display it) I am getting errors such as undeclared "navController", and "window". I don't believe the 3 lines belong in this app because I have the TabBar Controller, but I don't know what to replace them with to display the calendar.
How do I take my existing code and display the Kal calendar in the TabBar Controller's UIView?
You are right that you don't need the bottom 3 lines, but in fact, you don't need any of these lines. If you're using StoryBoards you should be able to setup your view stack entirely from there. The only thing you might need is to add the EventKit datasource to your Kal view controller, but you can do that from [KalViewController viewDidLoad:]. Your view stack should look like this:
Window -> Tab Bar Controller -> Nav Bar Controller -> Root View Controller
So by adding your Nav Bar view controller directly to the window, you're skipping the Tab bar controller entirely.

iOS: Trying to add Navigation Bar to Modal UITableViewController

I'm following the CoreDataRecipes app for modaly showing the add screen when I want to add a new item. However I cannot get the bar to display at the top so I can press 'Done' or 'Cancel'.
In the xib calling the modal controller I have the + button linked to modally sliding up the controller via IB.
I have the below in my modal controller
self.navigationItem.title = #"Add";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancel)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStyleDone target:self action:#selector(save)];
self.navigationController.navigationBarHidden = NO;
In my viewDidLoad
The modal controller displays fine except there is no bar so I cannot leave that screen.
You need to add it before the popover is actually presented.
Where you create the modal popover, you need to create it inside a UINavigationController first.
So, do the following.
PopoverView *foo = [[PopoverView alloc] initWithNibName:#"PopoverView" bundle:nil];
// Here you pass through properties if you need too.
// ...
UINavigationController *navC = [[UINavigationController alloc] initWithRootView:foo];
[foo release];
[self.navigationController presentModalViewController:navC animated:YES];
That will give the modal view the navigation bar which you're trying to edit.
Alternatively, you could maintain your storyboard segue. In Xcode, select the view controller you are trying to transition to and embed it in a navigation controller.
Now in the viewDidLoad of that view controller, add:
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancel)];
and lastly the callback:
- (void)cancel {
[self dismissModalViewControllerAnimated:YES];
}
Or if you just need the look of the bar, not exactly its functionality, you could drag the Navigation Bar (UINavigationBar) or Toolbar (UIToolbar) controll from the Media Library panel onto your view and go from there.
I had a similar predicament whereby I was loading a UITableViewController in a containerView. The containerView was inside a UIViewController which was being presented in a modal fashion.
I, like you, needed the navigation bar to have a title and a Done/Cancel button.
After overflowing the stack, I finally did this -
Dragged a UIView as the first item in the Table View in the IB. This automatically took a height of 44 pts and snapped to the top. It also shifted my first section downwards.
I dragged a UIButton (Done button) inside this view. Created an IBOutlet to it and called
[self dismissViewControllerAnimated:YES completion:nil];
Disclaimer:
1) This fake nav-bar will scroll along with the tableview.
2) This might not be a solution for what Bot has asked, but it's an option for others who might be looking for something similar.

In TabBarController + NavigationController mix env, how to reset nav when tab changes?

I am building an app, which has TabBarController, and each tab view has navigation view controller. When user click tab, I'd like the relavent navigation view controller to "reset" to the root panel.
In my code, I uses the following way to initialize the tab and navigation controller.
viewController1 = [[MyFirstController alloc] init];
UINavigationController *tableNavController = [[[UINavigationController alloc] initWithRootViewController:viewController1] autorelease];
viewController2 = [[MySecondController alloc] init];
UINavigationController *table2NavController = [[[UINavigationController alloc] initWithRootViewController:viewController2] autorelease];
tabBarController.viewControllers = [NSArray arrayWithObjects:tableNavController, table2NavController, nil];
Then appears that all the tab and navigation controller is working automatically. I am not sure where to cut in to let navigation controller view to reset when it is selected.
Thanks.
The navigation controller is sent a viewWillAppear message by the system, so you can implement the method to do the resetting..
Another option would be to use the tab bar controller's selectedViewController method to retrieve the selected navigation controller..
Hope that helps..