UITabBarControllerDelegate compare value of viewController - iphone

I have a tabBar with 4 tabs on it, and I want to perform some action when a specific tab is selected, so I have uncommented the UITabBarControllerDelegate in the xxAppDelegate.m
I also wanted to see the value that was being sent logged in the console - in order to test my "if" statement. However this is where I got stumped.
// Optional UITabBarControllerDelegate method
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(#"%#", viewController);
}
The console dutifully logged any selected controller that had been selected, but in this particular format:
<MyViewController: 0x3b12950>
Now, I wasn't expecting the square brackets or the colon or the Hex. So my question is how do I format my IF statement? This is what I thought would work but I get an error mentioned further down.
// Optional UITabBarControllerDelegate method
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(#"%#", viewController);
if (viewController == MyViewController)
{
//do something nice here …
};
}
... The error is "Expected expression before 'MyViewController'"
Anyone know how I should be doing this?

You need to compare to a specific view controller instance. For example, if the if statement should be true when the second tab is selected:
if (viewController == [tabBarController.viewControllers objectAtIndex:1]) {
// ...
}

Thanks that worked. I guess you have to know what object your comparing against first.
For anyone reading this the code supplied works, however you need to be careful that the text "tabBarController" in the example refers to the instance variable (the global one).
In order for your code to work your view controller needs to refer to a uniquely named local version as follows. Compare this to my original code.
// Optional UITabBarControllerDelegate method
- (void)tabBarController:(UITabBarController *)tabBarController_local didSelectViewController:(UIViewController *)viewController
{
//...
}
Hope this helps someone faced with the
Local declaration of 'tabBarController' hides instance variable
warning when trying to implement.

When comparing tabbarcontroller use self , like this:
if (viewController == [self.tabBarController.viewControllers objectAtIndex:1]) {
// ...
}
It will remove the warning.

Related

Compare instances or objects of same UIViewController class

I have created two instances of a MasterViewController derived from UIViewController class
_masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController_iPhone" bundle:nil];
// second instance with same class and duplicate nib view
_favItemMasterVC = [[MasterViewController alloc] initWithNibName:#"favMasterViewController_iPhone" bundle:nil];
Both the MasterViewController_iPhone & favMasterViewController_iPhone view are same.
Now I want to check which of the UIViewController is currently selected(eg:on tabbar).
How can i find the difference between both objects?
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[_favItemListMasterVC class]]
{ // it is always called in both cases}
isMemberOfClass: // is also not working
How to check the difference?
Not sure I have understand what are you doing, but if _favItemListMasterVC and _masterViewController are pointing to the same VCs added to the UITabBar, you can check it simply comparing pointers
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
if (viewController == _favItemListMasterVC)
{
//the visible view controller is _favItemListMasterVC
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
if (viewController == _masterViewController)
{
}
else if (viewController == _favItemMasterVC)
{
}
}
I think you can use tag to check which is which. Tag is property of a UIView Set the tag value in the two xib files. And check the tag using code.
To compare objects you can also use:
if([viewController isEqual:_favItemMasterVC])

How to change the action of the first tabbaritem (when clicked)

I'm trying to show a tableviewcontroller as the first page, with the tabbarcontroller in it.
After it is shown I would like to change the action of the first item in the tabbarcontroller to show a menu.
I have created the menu, I only need to find a way to change the click event of the first item on the tabbarcontroller.
I've been searching for hours now, and help would be greatly appreciated!
Thanks in advance,
Tommy
*edit: I found the solution, I will post it tomorrow!
Implement
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{
if(tabBar.selectedItem.tag == 0)
{
RootViewController *objRootViewController = [[RootViewController alloc]init];
[self.navigationController pushViewController:objRootViewController animated:YES];
[objRootViewController release];
}
}
I found out a good way to handle this problem...
I used the UITabBarController delegate and implemented this:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
if([viewController.title isEqualToString:#"YourTitleHere"])
{
// do your stuff here
}else
{
return YES;
}
}
this Worked great for me, very happy that I finally found a solution! Hope this helps others as well!

duplicate declaration of method dismissviewdidfinish

Have two actionsheet buttons and one modalviewcontroller on mainviewcontroller in application. Now for two actionsheet buttons and for modalviewcontroller, can i have multiple dismissviewdidfinish method for each
-(void)dismissViewDidFinish:(ModalViewController *)controller
{
[self dismissModalViewControllerAnimated:YES];
}
-(void)dismissViewDidFinish:(Devanagari *)controller1;
{
[self dismissViewControllerAnimated:completion];
}
-(void)dismissViewDidFinish:(English *)controller2;
{
[self dismissViewControllerAnimated:YES];
}
Cause if i add these three methods on mainviewcontroller i get red warning message duplicate declaration of method dismissviewdidfinish.
Any ideas how to solve this kind of situation.
You cannot have the same name for more than 1 method. Use a single dismissViewDidFinish:(UIViewController *)viewController method and then check to see which viewController finished:
- (void)dismissViewDidFinish:(UIViewController *)viewController {
//check to see what kind of class viewController is
//or use tags by setting the viewcontroller.view.tag when creating it
}

tabBarController:shouldSelectViewController method doesn't fire

I have read the Apple docs - http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/TabBarControllers/TabBarControllers.html#//apple_ref/doc/uid/TP40007457-CH102-SW1 about creating TabBar programmatically. I want to detect the TabBar selection so I have used following delegate methods. I am not sure why but these methods don't get fired when I change the Tabs on my iPhone. Could anyone please provide some thought on what's going wrong here. It would be really helpful. Thanks.
- (BOOL)tabBarController:(UITabBarController *)tbController shouldSelectViewController:(UIViewController *)viewController
{
if (viewController == [tbController.viewControllers objectAtIndex:3] )
{
// Enable all but the last tab.
return NO;
}
return YES;
}
- (void)tabBarController:(UITabBarController *)tbController didSelectViewController:(UIViewController *)viewController {
if (viewController == [tbController.viewControllers objectAtIndex:self.appTabs.count] )
{
//do some action
}
}
Did you forget to set the delegate when you created the UITabBarController?
someTabBarController.delegate = self;

How to determine what the prior visibleViewController in UINavigationControllers?

I'm switching views in the context of a navigation view heirarchy, and I want to be able to determine at switch time what the prior view was that is being pushed under the new view.
I'm trying this in a UINavigationControllerDelegate:
(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSLog( #"Switching from %# to %#",
NSStringFromClass( [[navigationController visibleViewController] class] ),
NSStringFromClass( [viewController class] )
);
}
I get this:
2009-08-05 20:05:21.274 App Name [85913:20b] Switching from
ManagementScreen to ManagementScreen
unfortunately it appears that before "will" is called, it is already swapped out in the state of the UINavigationController such that viewController passed in is always the same as the visibleViewController on the UINavigationController (and also the topViewController property, not demonstrated here but I tried it with the same code).
I would like to avoid extending the navigation view controller, and honestly while I can easily put a property on the delegate - however I'm wondering if this behavior is possible within the existing framework (seems will should be called before it happens where as did happens after, but it seems the state of the navigation controller is modified before either).
Thanks!
I don't think the answers that use the UINavigationControllerDelegate work because, as the question points out, by the time the delegate is called the view controller that will be displayed is already the value for navigationController.topViewController and navigationController.visibleViewController.
Instead, use observers.
Step 1. Set up an observer to watch for the UINavigationControllerWillShowViewController notification:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(viewControllerChange:) name:#"UINavigationControllerWillShowViewControllerNotification" object:self.navigationController];
Step 2. Create the notification callback (in this example called viewControllerChange) and use keys in the notifications userInfo dictionary to see the last and next view controllers:
(void)viewControllerChange:(NSNotification *)notification {
NSDictionary *userInfo = [notification userInfo];
NSLog(#"Switching from %# to %#", [[userInfo objectForKey:#"UINavigationControllerLastVisibleViewController"] class], [[userInfo objectForKey:#"UINavigationControllerNextVisibleViewController"] class]);
}
- (void)navigationController:(UINavigationController*)nc
didShowViewController:(UIViewController*)vc
animated:(BOOL)animated
{
NSLog(#"Switching from %# to %#",
NSStringFromClass([vc class]),
NSStringFromClass([[nc.viewControllers objectAtIndex:[nc.viewControllers count]-1] class]));
}