Setting badge on pushed UITabBarController - iphone

When a user clicks on a button, I create a UITabBarController with two viewcontrollers attached to it.
I then push the TabBarController onto my navigationController stack and it displays without problems. The problem is trying to set a badge on one of the tab bar items when the tabbarControlelr is loaded, I tried:
[[self.tabBarController.viewControllers objectAtIndex:1] setBadgeValue:#"1"];
and a whole lot of variations of this one, but none gives me a round red button thingy on the tabbar item.
Any suggestions?
Thanks,
Ron
EDIT
Code how I present the tabBarController
Airline_RosterAppDelegate *appDelegate = (Airline_RosterAppDelegate *)[[UIApplication sharedApplication] delegate];
CrewHere *vc = [[CrewHere alloc] initWithNibName:#"CrewHere" bundle:nil];
vc.title = #"Crewlist";
MessagesDetailed *mvc = [[MessagesDetailed alloc] initWithNibName:#"MessagesDetailed" bundle:nil];
mvc.title = #"Messageboard";
[tabbar setViewControllers:[NSArray arrayWithObjects:vc, mvc, nil]];
[tabbar setToolbarItems:[NSArray arrayWithObjects:#"Crewlist", #"Messageboard", nil]];
[appDelegate.navigationController pushViewController:tabbar animated:YES];

The property 'badgeValue' is defined on a UITabBarItem. You would set it with:
UITabBarItem *item = [self.tabBarController.tabBar.items objectAtIndex: 1];
item.badgeValue = #"1";
...
The above won't work, nor will your code, when 'the UITabBarController is loaded.' You can only do it after the controller appears because only at that point can you be sure that all the view elements actually exist. Put it in viewDidAppear:animated: for the tabBarController
[Edit, after your Edit]
You can't call setToolbarItems: with an NSArray of NSString; the array needs UITabBarItem. Instantiate with - (id)initWithTitle:(NSString *)title image:(UIImage *)image tag:(NSInteger)tag
Also, it appears that you are mixing tool bar and tab bar - they are different.

Related

How to dismiss UISplitViewController when a button pressed

In my iPad app. I'm working on UISplitViewController. In the DetailViewController of UISplitViewController there is button. When that button is pressed it's navigate to another view controller. In the another view controller I no need to UISplitViewController. How to dismiss UISplitViewController. I have tried a lot and googled,but I did not find any solution. It's killing my time so if any one have worked on it please guide me and post sample code.
I'm using this code
-(void)imgButtonpressed:(id)sender
{
MenuItemsListViewController *menuview=[[MenuItemsListViewController alloc]initWithNibName:#"MenuItemsListViewController" bundle:nil];
menuview.modelArray = imagesArray;
menuview.image = [sender tag]*2;
[self.navigationController pushViewController:menuview animated:YES];
}
I've had the same problem when working with UISplitView. In fact, i still got a problem now when i finally figured out how to push a splitview on top of a rootviewcontroller.
So, I believe there are lots of newbs out there who are frustrated by this problem. I tried to figure out the solution by lots of reading here.
Here's what i do (you can do the same with any other view) :
This will dismiss a splitview and push another splitview:
SplitViewController *split = [[SplitViewController alloc]init];
self.leftController = [[LeftViewController alloc]init];
UINavigationController *leftNav = [[UINavigationController alloc]initWithRootViewController:leftController];
self.rightController = [[RightViewController alloc]init];
UINavigationController *rightNav = [[UINavigationController alloc]initWithRootViewController:rightController];
split.viewControllers = [NSArray arrayWithObjects:leftNav,rightNav, nil];
split.delegate = self.rightController;
YourAppDelegate *delegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
delegate.window.rootViewController = split;
And the second option is :
NSMutableArray *allViewControllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
[allViewControllers replaceObjectAtIndex:0 withObject:split];
self.navigationController.viewControllers = allViewControllers;
Hopefully this would be a help to others who are stumbled with the same problem.
Cheers!
Apple doesn't want you to push split view controllers into navigation controllers. Their guidelines say that if you use a UISplitViewController, it has to be visible at all times in your app(Hence you cannot delete it), except from overlaying it with modal view controllers.
How about presenting your viewcontroller modally?
MenuItemsListViewController *menuview=[[MenuItemsListViewController alloc]initWithNibName:#"MenuItemsListViewController" bundle:nil];
menuview.modalPresentationStyle = UIModalPresentationFullScreen;
[self.splitViewController presentViewController:menuview animated:YES completion:nil];
source: How can we push UISplitVIewController to a UINavigationController

Right design pattern for tabbed navigation views?

I've been stuck trying to puzzle this out for a couple days now, and I'll admit I need help.
The root view controller of my application is a tab bar controller. I want to have each tab bar a different navigation controller. These navigation controllers have completely different behavior.
So how do I set this up in terms of classes? Per Apple's documentation, I'm not supposed to subclass UINavigationViewController. So where do I put the code that drives each of these navigation controllers? Does it all get thrown in App Delegate? That would create an impossible mess.
This app should run on iOS 4.0 or later. (Realistically, I can probably require iOS 4.2.)
This is taken from one of my applications. As you say, you are not supposed to subclass UINavigationController, instead you use them as they are and you add viewcontroller on the UINavigationController's. Then after setting the root viewcontroller in each UINavigationController, you add the UINavigationController to the UITabBarController (phew!).
So each tab will "point" to a UINavigationController which has a regular viewcontroller as root viewcontroller, and it is the root viewcontroller (the one you add) that will be shown when a tab is pressed with a (optional) navigationbar at top.
UITabBarController *tvc = [[UITabBarController alloc] init];
self.tabBarController = tvc;
[tvc release];
// Instantiates three view-controllers which will be attached to the tabbar.
// Each view-controller is attached as rootviewcontroller in a navigationcontroller.
MainScreenViewController *vc1 = [[MainScreenViewController alloc] init];
PracticalMainViewController *vc2 = [[PracticalMainViewController alloc] init];
ExerciseViewController *vc3 = [[ExerciseViewController alloc] init];
UINavigationController *nvc1 = [[UINavigationController alloc] initWithRootViewController:vc1];
UINavigationController *nvc2 = [[UINavigationController alloc] initWithRootViewController:vc2];
UINavigationController *nvc3 = [[UINavigationController alloc] initWithRootViewController:vc3];
[vc1 release];
[vc2 release];
[vc3 release];
nvc1.navigationBar.barStyle = UIBarStyleBlack;
nvc2.navigationBar.barStyle = UIBarStyleBlack;
nvc3.navigationBar.barStyle = UIBarStyleBlack;
NSArray *controllers = [[NSArray alloc] initWithObjects:nvc1, nvc2, nvc3, nil];
[nvc1 release];
[nvc2 release];
[nvc3 release];
self.tabBarController.viewControllers = controllers;
[controllers release];
This is how I go from one viewcontroller to another one (this is done by tapping a cell in a tableview but as you see the pushViewController method can be used wherever you want).
(this is taken from another part of the app)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.detailedAnswerViewController == nil) {
TestAnsweredViewController *vc = [[TestAnsweredViewController alloc] init];
self.detailedAnswerViewController = vc;
[vc release];
}
[self.navigationController pushViewController:self.detailedAnswerViewController animated:YES];
}
The self.navigationcontroller property is of course set on each viewcontroller which are pushed on the UINavigationController hierachy.

access methods and variables in first navigation controller from pushed view

I normally use UIViews to make my apps - but this one I am using a navigationcontroller. I am pushing a view to the top where I want to add items to an array. However, I cannot access the main navigation controller methods etc. Here's the set up
1) AppDelegate adds navigation controller
[window addSubview:navigationController.view];
2) In RootViewController I push a new UIView
AddNewViewController *addNewViewController = [[AddNewViewController alloc] init];
[self presentModalViewController: addNewViewController animated:YES];
3) From the AddNewViewController I then want to access the main RootViewController - but cannot seem to access anything. All the methods etc are declared as I've done it before (using UIViews). This code cannot find anything in the RootViewController.
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.navigationController myFunction];
I have myFunction in the RootViewController.h file. I have used this method before, but never with a navigation controller. I guess it's something to do with hte stack - but I cannot find out what I've done wrong!
Help is much appreciated!!
* UPDATE *
I have now used
AddNewViewController *addNewViewController = [[AddNewViewController alloc] init];
[self.navigationController pushViewController:addNewViewController animated:YES];
to push the view controller. In my code, I am trying to access the tableview to reload it with the following code
[self.navigationController.mainTableView reloadData];
but the mainTableView is not accessible. I have declared and sync'd it but still cannot see it. I also tried to loop through and use the element[0] of the stack (as below) but didn't get anywhere with that either!
NSArray *controllers = [[NSArray alloc] initWithObjects:self.navigationController.viewControllers, nil];
UIViewController *tmpController = [[UIViewController alloc] init];
tmpController = [controllers objectAtIndex:0];
First of all,
[self presentModalViewController: addNewViewController animated:YES];
does something different than
[self.navigationController pushViewController:addNewViewController animated:YES];
The names of those methods should speak for themselves.
And appDelegate.navigationController is not your rootViewController. It is the UINavigationController. You can get an NSArray of viewControllers attached to the navigationcontroller with self.navigationController.viewControllers. Item at index 0 should be your rootViewController.
If you push the viewController on the navigationControllers stack there is no need to use the appdelegate. You can access the navigationController with self.navigationController.

How to pushviewcontroller to a viewcontroller stored in a tabbaritem?

First of all I know this is a long question. REST ASSURED I have tried to figure it out on my own (see: StackOverflow #2609318). This is driving me BATTY!
After trying and failing to implement my own EDIT feature in the standard moreNavigationController, I have decided to re-implement my own MORE feature.
I did the following:
Add a HOME view controller which I init with: initWithRootViewController
Add 3 other default tabs with:
ResortsListViewController *resortsListViewController;
resortsListViewController = [[ResortsListViewController alloc] initWithNibName:#"ResortsListView" bundle:nil];
resortsListViewController.title = [categoriesDictionary objectForKey:#"category_name"];
resortsListViewController.tabBarItem.image = [UIImage imageNamed:#"whatever.png"];
resortsListViewController.navigationItem.title=#"whatever title";
localNavigationController = [[UINavigationController alloc] initWithRootViewController:resortsListViewController];
localNavigationController.navigationBar.barStyle = UIBarStyleBlack;
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[resortsListViewController release];
Those work when i add them to the tabbar. (ie: click on them and it goes to the view controller)
Then I add my own MORE view controller to the tabbar:
MoreViewController *moreViewController;
moreViewController = [[MoreViewController alloc] initWithNibName:#"MoreView" bundle:nil];
moreViewController.title = #"More";
moreViewController.tabBarItem.image = [UIImage imageNamed:#"more.png"];
moreViewController.navigationItem.title=#"More Categories";
localNavigationController = [[UINavigationController alloc] initWithRootViewController:moreViewController];
localNavigationController.navigationBar.barStyle = UIBarStyleBlack;
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[moreViewController release];
Then
tabBarController.viewControllers = localControllersArray;
tabBarController.moreNavigationController.navigationBar.barStyle = UIBarStyleBlack;
tabBarController.customizableViewControllers = [NSArray arrayWithObjects:nil];
tabBarController.delegate = self;
That creates the necessary linkages. Okay, so far all is well. I get a HOME tab, 3 category tabs and a customized MORE tab -- which all work.
in the MORE tab view controller I implement a simple table view that displays all the other tabs I have in rows. SINCE I want to be able to switch them in and out of the tabbar I created them JUST like i did the resortslistviewcontroller above (ie: as view controllers in an array). When I pull them out to display the title in the tableview (so the user can go to that "view") i simply do the following:
// [myGizmoClass CategoryArray] holds the array of view controller tab bar items that are NOT shown on the main screen.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
... etc...
UIViewController *Uivc = [[myGizmoClass plusCategoryArray] objectAtIndex:indexPath.row];
cell.textLabel.text = [Uivc title];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
THIS is where it falls through:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MyGizmoClass *myGizmoClass= [MyGizmoClass sharedManager];
UIViewController *tbi = [[myGizmoClass plusCategoryArray] objectAtIndex:indexPath.row];
NSLog(#"%#\n",[[tbi navigationItem ]title]);
[self.navigationController pushViewController:tbi animated:YES];
}
This is the error i get ("ATMs" is the title for the clicked tableview cell) so i know the Uivc title is pulling the correct title and therefore the correct "objectatindex":
2010-04-09 11:25:48.222
MouseAddict[47485:207] ATMs 2010-04-09
11:25:48.222 MouseAddict[47485:207]
*** Terminating app due to uncaught exception
'NSInvalidArgumentException', reason:
'Pushing a navigation controller is
not supported'
BIG QUESTION: How do i make the associated VIEW of the UIViewController *tbi show and get pushed into view?
I am GUESSING that the UIViewController is the correct class for this tbl .. i am not sure. BUT i just wanna get the view so i can push it onto the stack.
Can someone plz help?
To answer kovpas's question below: myGizmoClass is a singleton (apple's singleton myGizmo class. The array of viewcontrollers is stored in that just like it is in [localControllersArray addObject:localNavigationController]; (in the first code snippet above). AND it does put it in and pull it out correctly as evidenced by the fact that when i NSLOG the [Uivc title] the log prints ATMs. This means the plusCategoryArray is correctly storing and retrieving the viewController (if, indeed, that is what is being stored).
Pushing a navigation controller is not supported is really bothering me. Why would a viewController return a navigationController and is it possible to coerce the navigationController to get the "pushable" view out of it... or does the navigationController have some element in it that is the view?
From the error, it looks as if your Gizmo class has an array of UINavigationControllers, not UIViewControllers. So instead push with:
[self.navigationController pushViewController:[[tbi viewControllers] lastObject] animated:YES];
If the array is the same array as you called localControllers above, then this should work better. Or you could just create the array without the UINavigationControllers, they aren't needed if you are going to push them onto your more controller navigation controller.
I'm not sure, but it looks like this error appears when you are trying to push UINavigationController into another UINavigationController. Could you please provide an implementation of MyGizmoClass?

iphone presentModalViewController

I have an app, inside that an UIViewController is attached on the UIWindow.
on the view of UIViewController, i have added a button and a uiview_1 of size 100x80.
this uiview_1 contains another uiview_2 as subview of same size and this uiview_2 contains a UIImageView or a UIlable at runtime (both UIImageView and UIlable are userinteraction enabled)
now on the touch/click of UIImageView, i want to show a new view using presentModalViewController, the problem is the view is shown and using back button on the navigation bar i come to the previous/main screen.
here the problem come in picture, now i am unable to touch the button or the UIImageView.
both are not responding, but app is not crashed and nor frozen.
what is wrong in that?
Plz help in this...
----- EDIT:
Approach First:
SWVController *swvController = [[SWVController alloc] init];
UINavigationController *viewNavController = [[UINavigationController alloc] initWithRootViewController:swvController];
UIViewController *pushController = [[UIViewController alloc] init];
UIWindow *win = [[UIApplication sharedApplication] keyWindow];
[win addSubview:pushController.view];
[pushController presentModalViewController:viewNavController animated:YES];
In the swvController i have back button that calls the dismissModelViewController on click >> result is the Main screen ctrls are not responding to touch – sandy 3 hours ago
Second approach:
SWVController *swvController = [[SWVController alloc] init];
UINavigationController *viewNavController = [[UINavigationController alloc] initWithRootViewController:swvController];
UIViewController *pushController = [[UIViewController alloc] init];
[self addSubview:pushController.view];
[pushController presentModalViewController:viewNavController animated:YES];
In the swvController i have back button that calls the dismissModelViewController on click >> result is the swvController's back button on navbar is not responding – sandy 3 hours ago
3rd approach:
SWVController *swvController = [[SWVController alloc] init];
UINavigationController *viewNavController = [[UINavigationController alloc] initWithRootViewController:swvController];
SampleAppAppDelegate *appdel = [[UIApplication sharedApplication] delegate]; [appdel.viewController presentModalViewController:viewNavController animated:YES];
>> result is working fine, but the problem is i dont want to use SampleAppAppDelegate,i want to give my small Uiview (100x80) as a ctrl to other person , where my ctrl will not able to get the AppDelegate of thet app at run time. – sandy 3 hours ago
Call this method when you want to present the modal view controller:
- (IBAction)showInfo {
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
Add this method to your self:
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller {
[self dismissModalViewControllerAnimated:YES];
}
Use a toolbar or other button and connect it to this method in your modal view controller:
- (IBAction)done {
[self.delegate flipsideViewControllerDidFinish:self];
}
All code comes from Apple.
How did you handled click/touch on UIImageView? TouchesBegan/Ended?
Try putting some logs (NSLog) and run your app in debug mode (put some breakpoints) to see if control reaches your action method...
Also, when you do presentModalViewController, you do not need to POP out with back button on navigation bar... you only need to dismissModelViewController to hide it.