I have a UITabController in my main window, and would like to add some logic when each tab is selected. I've added the delegate to the header file:
#interface MyAppAppDelegate : NSObject <UIApplicationDelegate, UITabBarDelegate> {
I have a method for the tab change event:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{
//some code
}
But the code inside the didSelectItem method isn't called. I've connected the delegate for the UITabBarController to my AppDelegate in IB. Is there anything else I need to do?
If you assign the delegate via IB, you should connect the delegate for your TabBar (as opposed to your TabBarController) to your app delegate.
Indeed, you are not looking for the UITabBarControllerDelegate, but for the UITabBarDelegate.
If you do it programmatically, then, from your tab bar controller viewDidLoad execute:
self.tabBar.delegate = [UIApplication sharedApplication].delegate;
If you use UITabbarController you can use UITabBarControllerDelegate instead of UITabBarDelegate.
Then, you can set self.delegate = self. Then you use:
(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;
instead of:
(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item;
Did you assign some class to be the tab bar's delegate? Something like
myTabBar.delegate = self;
i might be out on a ledge here but i think the signature of the method should be:
- (IBAction)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
and then you connect it to the tabbar in IB. after you change to IBAction it should appear in IB
I ended up putting it in the viewWillAppear method of the view in the specific tab I need. Seems to work fine.
Related
I have two view controllers (FirstViewController and SecondViewController) and a Tab Bar Controller and I'm using Storyboards. In the FirstViewController user can drag and drop an imageview. So every time a user clicks on the second TabBarItem which displays the SecondViewController I would like to check if the user has dropped the image or not every time she clicks the TabBarItem.
So I understand that this can be done with UITabBarDelegate and with its method -(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item. But I'm doing something wrong because the method isn't called and I believe this is because I can't set the delegate properly. So I want the SecondViewController to be the delegate for TabBarController.
So in my SecondViewController.h I have the following
#interface SecondViewController : UIViewController<UITabBarDelegate>
And in SecondViewController.m I have
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
NSLog(#"%#", item);
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.tabBarController.delegate = self;
}
But nothing happens and when setting the delegate I also get a compiler warning: Assigning to 'id' from incompatible type 'SecondViewController *const __strong'
Please be gentle with me, this is my first app and the first time I'm trying to use delegates.
Add the following code to any of the view controllers
UITabBarController *tabBarController = (UITabBarController*)[UIApplication sharedApplication].keyWindow.rootViewController ;
[tabBarController setDelegate:self];
// add any delegates methods to your class
-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(#"%#", tabBarController);
}
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item;
This method is a delegate method for UITabBar, not UITabBarController, so
self.tabBarController.delegate = self;
will not work.
Tab bar controller has its own UITabBar, but changing the delegate of a tab bar managed by a tab bar controller is not allowed, so just try UITabBarControllerDelegate method like this:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
NSLog(#"%#", item);
}
For more detail check info
Thanks
I imported and implemented the following. Hope it helps.
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
if (_mainTab.selectedItem.tag == 1) {
NSLog(#"TAB 1");
}
else if (_mainTab.selectedItem.tag == 2) {
NSLog(#"TAB2");
}
else if (_mainTab.selectedItem.tag == 3)
{
NSLog(#"TAB3");
}
else
{
NSLog(#"TAB NOT WORKING");
}
}
You are using the wrong delegate protocol UITabBarDelegate is usually used for customizing the UITabBar objects. You need to use UITabBarControllerDelegate protocol in order to check if a tab is selected or customize the behavior of tabs.
You should implement UITabBarControllerDelegate protocol instead and use this delegates callback to track selection:
tabBarController:didSelectViewController:
Next thing is, that you should initialize delegate before it will be called. ViewDidLoad will be called after tabbarcontroller will try to talk to delegate.
In order to get rid of the compiler warning your SecondViewController should conform to the UITabBarControllerDelegate protocol instead of the UITabBarDelegate protocol.
#interface SecondViewController : UIViewController<UITabBarControllerDelegate>
I think I've done my homework here.
I want my app delegate to be the delegate for my UITabBarController.
Using IB, I've connected UITabBarController's delegate to my Application Delegate.
App Delegate Header file is:
#interface MyAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
The delegate method I'm trying to implement is:
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
NSLog(#"shouldSelectViewController called.");
// do some stuff with viewController
return YES;
}
My app delegate has an outlet to the UITabBarController that's connected in IB. When I do this:
NSLog(#"tab bar controller delegate is %#", self.tabBarController.delegate);
I get a good result such as tab bar controller delegate is <MyAppDelegate: 0x6e86a30>.
What am I missing?
Just write this code. Usually in viewDidLoad().
self.tabBarController.delegate = self;
If the current controller is a UITabBarController then:
self.delegate = self
Ok, found the solution. I had some old code in my RootViewController that set up this controller as the delegate. No delegate methods were implemented on the RootViewController, so it appeared as if nothing was happening. Because the RootViewController is set as delegate AFTER MyAppDelegate, the delegate was actually set to the RootViewController.
So the lesson is double-check your code to make sure some other object isn't also being set as the delegate.
I'm still relatively new to iPhone development but I know this warning is usually the result of not declaring a method in my classes header file. This is slightly different - at least I think it is.
I've created a custom tab bar in my applications root view controller which loads in the other view controllers dynamically inside the delegate method - essentially like this:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
UIViewController *viewController = [viewControllers objectAtIndex:item.tag];
[self.selectedViewController.view removeFromSuperview];
[self.view insertSubview:viewController.view atIndex:0];
self.selectedViewController = viewController;
}
That code works fine and loads in the required views. When the view changes a check is run to see if the setting view is about to be unloaded and if so it calls the save settings method like this:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
if (self.currentController == 1) {
[self.selectedViewController saveSettings];
}
UIViewController *viewController = [viewControllers objectAtIndex:item.tag];
[self.selectedViewController.view removeFromSuperview];
[self.view insertSubview:viewController.view atIndex:0];
self.selectedViewController = viewController;
}
Again the code functions fine and the instance method of SettingsViewController is called, but because the declaration of the method is in the header of the SettingsViewController and not the RootViewController hence the warning.
If I declare it in the RootViewController as well I get the 'no matching method declaration' warning. I presume redeclaring my function would fix the warning - but surely isn't the 'proper' way to fix this.
If I understand your question correctly, this should work:
if (self.currentController == 1) {
[(SettingsViewController *)self.selectedViewController saveSettings];
}
Can any one help me,
when i am using my UITabBarController delegate it is not working..
I called a delegate method like this..
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
[self.navigationController popToRootViewControllerAnimated:NO];
}
If what you're doing is subclassing a UITabBarController, then... oddly enough... you can get it working by setting itself as a delegate:
- (void)viewDidLoad
{
[super viewDidLoad];
self.delegate = self;
}
Then the didSelectViewController action will fire normally:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSLog(#"View Changed");
}
Don't forget to add your UITabBarControllerDelegate class to your .h file:
#interface MyTabBarController : UITabBarController <UITabBarControllerDelegate>
#end
If you are using tab bar customizing by extending UITabBarController and trying to change tab bar selected index programmatically then it will not call delegates.
Please see the note inside "UITabBarDelegate":
// Note: called when a new view is selected by the user (but not programmatically)
This might help you
-(void)applicationDidFinishLaunching:(UIApplication *)application {
tabBarController.delegate=self;
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
}
specify
UITabbarcontrollerDelegate in .h file
then
-(void)applicationDidFinishLaunching:(UIApplication *)application {
tabBarController.delegate=self;
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
}
Read the documents to get a deeper understanding of the relationships between navigation controllers, tabBar controllers, and the view and navigation hierarchy.
Then review the code you've provided. Which view/controller is the container? You are popping the navigationController of self, which is not the same as the tabBarController. I don't think you actually need this method if you are looking to switch between tabs.
Try commenting out this method. It is an optional method in the UITabBarController delegate protocol. If you comment it out, you should get the default behavior of the tab controller, which should be to select the appropriate viewController and switch to the new view.
You typically only need to use this method if you want some action taken as you switch between view controllers.
i have implemented Tab bar controller in IB.but when i write the following method in appdelegate.m , it is not called(i have put break point) when i tab ...?any help?
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
Wherever you create the UITabBarController, you need to set its delegate property to the custom UITabBarControllerDelegate object you've created.
If you've extended your application delegate to implement the methods of the UITabBarContollerDelegate protocol, and create the UITabBarController in the application delegate, then add the following after creating it:
tabBarVaribleName.delegate = self;