I don't use UITabbarController,I just add the UITabbar in ViewController.I know when we use UITabbarController,we will create one array which contain viewcontrollers,so when we tap the tab,will show the specific viewcontroller,but the UITabbar just can add UITabbarItems,so how to connect the viewcontroller to the Tab?just like UITabbarController. thank you in advance.
Attach a UITabBarDelegate to your UITabBar:
self.tabbar.delegate = self;
// make sure you declared self to be a UITabBarDelegate in your header
Then implement:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
// item is the selected tab bar item
}
Have your view controller implement the UITabBarDelegate protocol. Then set your tab bar's delegate property to point at your instance of your view controller. In your view controller class you can implement the tabBar:didSelectItem: method, which will get called whenever the user selects an item on your tab bar.
However, if you intend to use your tab bar to switch between different view controllers you should use a UITabBarController -- that's what it was designed to do.
Related
I am using UITabBarController so that it can be displayed on all views once declared in delegate, but my requirement is that when any tab bar button clicked it should work like a button works on pushViewController:. Is it possible, can anyone guide here.
Thanks in advance.
you can just create a UINavigationController with toolbar hidden.
Then create a root view controller which has toolbar or custom view on bottom and add buttons on it.
Add targets to that buttons to push view controllers which you want.
This is not a typical behavior, however you can try as follows:
Declare a delegate (UITabBarDelegate) for your UITabBar, and implement the method -(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item to get notified of the user selecting tabs. In this method you will push a new view controller in the navigation controller's stack (or pop one that is not desired).
Depending on your needs, you may also need to manually set the currently selected tab bar item. To do so you can manipulate the tab bar's #property(nonatomic) NSUInteger selectedIndex. Be aware that changing this property will trigger another call to tabBar:didSelectItem: which may or may not be wanted.
I have an application which has 5 tabs on a TabBarController. For simplicity sake lets say they are Tab A, B, C, D, and E. Each tab takes the user to a TableViewController which is embedded in a Navigation controller. Each tab also has its own specific .h and .m files. The code for the most part is very similar between the 5 tabs. I want to do away with these 5 sets of class files and just use 1 set. This will make it much easier for me to make changes to the application (in 1 place instead of 5 places). How can I detect in the single implementation file which tab was selected? Once I know that I can put logic in place to render the tableview specifically for which tab was selected...
Another thing I should mention is that I need to detect the selected Tab in the TableViewController. The TabBarController is the point of entry for the application and I do not have a TabBarController subclass.
I tried this code in the TableViewController however it does not get accessed and/or used.
in .h file:
#interface MyController : UITableViewController <UITabBarDelegate>
in .m file:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
//NSLog(#"selectedIndex: %d", self.tabBarController.selectedIndex);
NSLog(#"didSelectItem: %d", item.tag);
}
Easy, You already have the solution!
tabBarController
A parent or ancestor that is a tab bar controller.
(read-only)
#property(nonatomic, readonly, retain) UITabBarController *tabBarController
Discussion If the receiver is added to a tab bar controller, this property is the tab bar controller. If the receiver’s
navigation controller is added to a tab bar controller, this property
is the navigation controller’s tab bar controller. If no tab bar is
present or the receiver is a modal view, this property is nil.
That means that any viewController you add to a tab bar controller has this property filled in by the system.
Then in the view controller you want for the tab you implement viewWillAppear
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
NSUInteger selectedIndex = self.tabBarController.selectedIndex;
switch (selectedIndex) {
case 0:
//configure me
break;
case 1:
//configure me differently!!
break;
default:
break;
}
}
In light of the comments this property of tabBarController doesn't seem to be reliable.
The problem you describe sounds like something that could solved by subclassing. Make a subclass of UIViewController for the code in common with each tab and then subclass your subclass for each tabs viewController to make modifications unique to the tab.
Alternatively you could load each tab with the same class but a different xib. You can set properties on your view controller in the "user defined runtime attributes" section in interface builder. Then in the viewWillAppear block just check the property set by the xib on that instance.
If I understood you correctly, you have many choices:
- you may want to override the init method in your m file which I guess initializes a UITableViewCOntroller and pass an additional parameter to it depending on which tab you are in.
you may also want to add a tabid property to this class and set that when you are creating it for each tab (to something that shows which tab you are in).
you mat also use notifications (but it wont be the easiest or best solution, unless you have good reason not to use the first two)
I am sure there are lots of other ways.
Alternatively, I could use something like viewWillAppear, only switching tabs doesn't call viewWillAppear - IF I can access selectedItem or selectedIndex reliably from there.
The goal is to re-use a similar table view, with 3 tabs filling the table with differently filtered data.
I tried overriding didSelect and using the app delegate as UITabBarDelegate, but got the error 'Changing the delegate of a tab bar managed by a tab bar controller is not allowed.'
The tab bar controller, rootCt, is in the app delegate and works correctly.
So that's the trick I'm looking for - getting a notification from the root (tab bar) controller when the index has changed. Ideas?
Try implementing an UITabBarController delegate. It has a method similar to the didSelect: method offered by UITabBar delegate:
tabBarController:didSelectViewController:. It will be called after the user has selected another tab.
See: UITabBarControllerDelegate Protocol Reference
tabBarController.tabBar.selectedItem.tag
It will give you the tag of current selected tabbar index
If you are using tabBar den
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
is the delegate method that gets called when tabbar is selected.
happy iCoding...
You can use the delegate method of UITabBarControllerDelegate
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
and in that you have self.selectedIndex will give you the selected index.
I don't usually do this kind of thing (answer my own question). But here goes.
For example, if I click tab 2, then tab 3, then tab 2 again, viewWillAppear for that view is called, but the didSelectViewController method is not - and selectedIndex is not changed!
It appears as if selectedIndex is only updated if a view is loaded, not if the view is already loaded and simply appears.
I did some testing, and unlike selectedIndex, the tab bar's selectedItem is correctly updated (in viewWillAppear for the view in the clicked tab) even if the view is already loaded. By putting f.ex. the tabs' titles in an array, the matching index can be looked up.
So I will omit the didSelectViewController and won't need a UITabBarController, I only need to connect the UITabBar to an IBOutlet and use [myTabBar selectedItem].title to initialize correctly in the re-used view's viewWillAppear.
If someone offers a more generic/useful/simple solution I'll gladly mark that! Will check back in a few days and mark this if not. Just glad I made it work :)
I have an app with a navigation controller that I would like to add a tab bar to. Does anybody know if its possible to say something like if the fist tab is selected show view1 if tab 2 is selected show view2? If theres code for that then I would be good to go. Any help is appreciated. Y+Thanks
According the interface guidelines, a tabbar should always be at the top level of the app. In other words, you should have a tabbar and then have a navigation controller inside each tab.
If you need to display views as with a tabbar but not at the top level of the app, use a segmented control. Users will understand they are choosing alternate views but they won't be confused about where in the app they are.
You shouldn't be using a UITabBarView without a UITabBarViewController.
Why do you not want to use a TabBarController?
Otherwise you can simply add a tabbar and implement the UITabBarDelegate protocol to react to changes. Which is essentially implementing your own TabBarController.
You will need to create a Tabbar and set the delegate to an object that implements the following method, where you can switch view based on the selected tabbarItem:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
int index = [tabBar.items indexOfObject:item];
switch (index) ...
}
quick question - I have my "first view" which is going to be the ONLY view in my application. I've added a UITabBar to this view using Interface Builder. I am simply wanting to use this as a menu to control the contents of a scroll view.
For example, the user clicks on the first icon in the UITabBar - I get its tag, then based on that, will add a subview to the scrollview. This is working ok....
...but, I have been viewing a few tutorials on tabbars and it seems that 99% of the time they are used to control views. I simply want it to return my tags.
So my question is this: is what I am doing ok?? Can it be used for simply returning a value rather than changing a view? If this is common/OK practice, how on earth do I reference it?
I can get the selected item tag, but cannot actually reference the uiTabBar to make the first button selected. In my .h file, I tried to specify an IBOutlet for the controller, but I cannot link this in IB.
thanks for any info!
To receive notifications that a tab bar item has been clicked you need to modify your view controller to implement the UITabBarDelegate protocol and add an outlet for the tab bar. To do this, modify your declaration in MyViewController.h to something like this:
#interface MyViewController : UIViewController <UITabBarDelegate> {
UITabBar *tabBar;
...
}
#property (nonatomic, assign) IBOutlet UITabBar *tabBar;
Then implement the tabBar:didSelectItem method in MyViewController.m as follows:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
NSLog(#"Tab clicked: %d", item.tag);
}
You must also set your view controller as the delegate of the tab bar in IB. (hint: connect up the 'delegate' outlet from the tab bar to File's Owner).
To access the tab bar from your view controller use the tabBar property and do things like:
self.tabBar.selectedItem = [self.tabBar.items objectAtIndex:0];
As to whether this is a good idea - why not? All the tutorials show a tab bar being used with a UITabBarContoller to switch views, but it is designed to operate as a stand-alone control as well. As long as you are not breaking any HIG rules then how you implement your interface switching is up to you.