I am trying to include a tab bar, with 4-5 tab bar items on it, to multiple view controllers of my app and will work as menu to jump between views (Map, About, Favourites etc.).
I have created on Storyboard a UITabBar item and set its Bar item's tags. Because the same tab bar will be used on several other view controllers (Main, View2, View3 etc.) I've decided to create a class that extends UITabBar. This will help me to customise the bar later. The UITabBar object in Storyboard is now an object of this class (BottomTabBar).
My question is, how I can detect when a bar item has been tapped?
In addition, because I am not familiar with TabBar, if you have any general guides or tips that will help me during development please share them with me.
BottomTabBar.h
#import <UIKit/UIKit.h>
#interface BottomTabBar : UITabBar <UITabBarDelegate>
#end
BottomTabBar.m
#import "BottomTabBar.h"
#implementation BottomTabBar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.delegate = self;
}
return self;
}
- (void) tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{
NSLog(#"Tabbed!");
}
#end
MainViewController.h
#import <UIKit/UIKit.h>
#import "BottomTabBar.h"
#interface MainViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>{
AppDelegate *appDelegate;
NSArray *searchResults;
}
#property (strong, nonatomic) IBOutlet UIScrollView *slideshow;
#property (strong, nonatomic) IBOutlet UIPageControl *scroll;
#property (strong, nonatomic) IBOutlet BottomTabBar *bottomBar;
#end
This guide is really good:
http://www.rumex.it/2010/07/how-to-customise-the-tab-bar-uitabbar-in-an-iphone-application-part-1-of-2/
Notice there is also a second part there.
See this tutorials and source codes for custom tab bar.
Custom tabbar
I hope it helps you.
Related
I have added a Tab bar (not a TabViewController) to a View Controller and then added some Tab bar items to that Tab bar.
Now I want to attach other View Controllers to those tab bar items in Storyboard.
When I do Ctrl + Drag to View Controller from tab bar item I do not get any options.
Please suggest a way to do this.
I had the same problem, but i couldn't find a way to assign to a viewController its own viewControllers as in the TabViewController case.
I solved it using containers. One contarner for each tabBarItem in your tabBar, which are hidden or showed depending of the selected tabBarItem in the tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item method.
1. Create your containers in your UIviewController in storyBoard:
Just like this Select your tabBar and Ctrl+Drag to delegate the class for listen the tabBarDelegate methods: look here
2. Declare the corrisponging IBOutlets, incliding your tabBAr:
#import <UIKit/UIKit.h>
#interface TabsMainViewController : UIViewController
#property (strong, nonatomic) IBOutlet UITabBar *tabBar;
#property (strong, nonatomic) IBOutlet UIView *directoryContainer;
#property (strong, nonatomic) IBOutlet UIView *groupsContainer;
#end
3. Select the container to show in the tabBarDelegate method:
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
switch (item.tag) {
case 1:
_directoryContainer.hidden = NO;
_groupsContainer.hidden = YES;
break;
case 2:
_directoryContainer.hidden = YES;
_groupsContainer.hidden = NO;
break;
default:
break;
}
}
Hope that helps!
i tried using storyboard instantiateViewControllerWithIdentifier and it was working fine but i needed delegate method so i added below code when opening
SecondViewController from FirstViewController,
SecondViewController *svc=[[SeconViewController alloc] init];
svc.delegate=self;
[self.navigationController pushViewController:svc animated:YES];
but it opens black screen.any sort help is really appreciated. Thank you.
secondViewController.h file
#protocol sendDataToAudioDelegate <NSObject>
-(void)sendData:(NSMutableArray *) data;
#end
#interface AudioSavedFilesViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *fileTable;
#property (strong, nonatomic) NSMutableArray *selectedIndices;
#property (strong, nonatomic) AVAudioPlayer *audioplayer;
- (IBAction)selectedFiles:(id)sender;
#property (nonatomic,assign)id <sendDataToAudioDelegate> delegate;
#end
Here:
SecondViewController *svc= [self.storyboard instantiateViewControllerWithIdentifier #"identifier"];
svc.delegate=self;
You are trying to set SecondViewController's delegate property. But the error you are getting when doing so:
property delegate not found on object type 'UIViewController'
Suggest that your SecondViewController class does not have a property called delegate. Hence you need:
#interface SecondViewController
#property (nonatomic, assign) id delegate;
#end
The reason is because you're creating a completely new instance of SecondViewController and pushing it onto the navigationController. You're not using the storyboard scene at all, thus, all the UI elements you added and connected up won't work either. You'll need to revert to how you were doing it with instantiateViewControllerWithIdentifier
You can still use the delegate as you're doing so there like this:
SecondViewController *svc= [self.storyboard instantiateViewControllerWithIdentifier #"identifier"];
svc.delegate=self;
[self.navigationController pushViewController:svc animated:YES];
Edit
After reading your comments...
I think you haven't set the scene in your storyboard to use the SecondViewController.
So you need to replicate this:
I used a UIview controller for my app home page and then added a tab bar at the bottom just like Facebook and then added 3 more tab bar item, it doesn't let me perform a segue when drag the tab bar item to a View Controller, is it possible progmatically or in storyboard?
I had the same problem, but i couldn't find a way to assign to a viewController its own viewControllers as in the TabViewController case.
I solved it using containers. One container for each tabBarItem in your tabBar, which are hidden or showed depending of the selected tabBarItem in the tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item method.
1. Create your containers in your UIviewController in storyBoard: Just like this Select your tabBar and Ctrl+Drag to delegate the class for listen the tabBarDelegate methods: look here
2. Declare the corrisponging IBOutlets, incliding your tabBAr:
#import <UIKit/UIKit.h>
#interface TabsMainViewController : UIViewController
#property (strong, nonatomic) IBOutlet UITabBar *tabBar;
#property (strong, nonatomic) IBOutlet UIView *directoryContainer;
#property (strong, nonatomic) IBOutlet UIView *groupsContainer;
#end
3. Select the container to show in the tabBarDelegate method:
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
switch (item.tag) {
case 1:
_directoryContainer.hidden = NO;
_groupsContainer.hidden = YES;
break;
case 2:
_directoryContainer.hidden = YES;
_groupsContainer.hidden = NO;
break;
default:
break;
}
}
Hope that helps!
Simple: You need a UITabViewController, tab bar items can't be used the way you're asking for.
Ctrl+drag from your tabview controller to a view you'd like to include (Third in this case)
You then select the view controllers option to add the relationship segue.
I'd like to develop for iOS5 and have a storyboard...
I've just created UIView with UIViewController on the storyboard.
I have added a lot of other UIButtons and labels and creates outlets to VC.
I would like to use this view with it's viewcontroller 3 times on a single parent view.
How is it possible? I dont want to copy "a lot of other UIButtons and labels" ...
Maybe i should create this view out of storyboard in separate XIB? How will i use XIB in storyboard?
UPDATE:
Thanx you, Juzzz - your solution works perfect:
You have to create 2 custom viewControllers (one for each view in your story board.
example:
#interface GraphCollectionViewController : UIViewController
#interface GraphViewController : UIViewController
To connect them you can use something called: UIViewController containment
For your GraphCollectionViewController create 3 outlets for your UIViews. Then create 3 properties of GraphViewController's (or an array, what you want) and initialize them in the view did load.
#property (strong, nonatomic) IBOutlet UIView *topView;
#property (strong, nonatomic) IBOutlet UIView *middleView;
#property (strong, nonatomic) IBOutlet UIView *bottomView;
#property (strong, nonatomic) GraphViewController *topGraphViewController;
#property (strong, nonatomic) GraphViewController *middleGraphViewController;
#property (strong, nonatomic) GraphViewController *bottomGraphViewController;
...
//top graph
self.topGraphViewController = [storyboard instantiateViewControllerWithIdentifier:#"GraphViewController"]; //init with view from storyboard
self.topGraphViewController.view.frame = self.topView.bounds; //set frame the same
[self.view addSubview:self.topGraphViewController.view];
[self addChildViewController:self.topGraphViewController];
[self.topGraphViewController didMoveToParentViewController:self];
//middle graph
self.middleGraphViewController = [storyboard instantiateViewControllerWithIdentifier:#"GraphViewController"]; //init with view from storyboard
self.middleGraphViewController.view.frame = self.middleView.bounds; //set frame the same
[self.view addSubview:self.middleGraphViewController.view];
[self addChildViewController:self.middleGraphViewController];
[self.middleGraphViewController didMoveToParentViewController:self];
//bottom graph
self.bottomGraphViewController = [storyboard instantiateViewControllerWithIdentifier:#"GraphViewController"]; //init with view from storyboard
self.bottomGraphViewController.view.frame = self.bottomView.bounds; //set frame the same
[self.view addSubview:self.bottomGraphViewController.view];
[self addChildViewController:self.bottomGraphViewController];
[self.bottomGraphViewController didMoveToParentViewController:self];
I think you get the point. For more understanding this example .
You can create a new view class (with it's own .h, .m files) and base this on the ViewController you created yourself.
So as for code:
#interface ViewController : UIViewController
Let's say the above is your original ViewController that you want to use in other places.
This has buttons, labels, etc. in it.
When you create a new view class base it on your own instead of UIViewController class like this:
#interface MyNewController : ViewController
Now that MyNewController is based on ViewController you created earlier, it should have it's buttons, labels, etc. you created as well.
Edit: You might also have to change your view's base class in the storyboard.
Click on the view you want to change, look at the right hand side attributes window, under Custom Class choose your own controller, in this case ViewController.
I have added a UITabBar to a View-based application, hooked up my View Controller as follows:
#interface SomeViewController : UIViewController<UITabBarDelegate> {
...
UITabBar *tabBar;
...
#property (nonatomic, retain) IBOutlet UITabBar *tabBar;
Inside my implementation file I have done this:
#synthesize tabBar;
- (void)tabBar: (UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
}
I went into IB and hooked tabBar up to File's Owner tabBar.
My problem: clicking on a tab bar item never fires off the didSelectItem method. Am I missing or mis-doing a step?
Did you set the delegate of the tabbar to self?