Image position inside UITabBarItem - iphone

I'm using code to shown a UITabBar with items, I downloaded an example that show item with system icons of "favorites" "contacts" ...
UITabBarItem *favorites = [[UITabBarItem alloc] initWithTitle:nil image:a1 tag:0];
UITabBarItem *topRated = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemTopRated tag:1];
UITabBarItem *featured = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemFeatured tag:2];
UITabBarItem *recents = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemRecents tag:3];
I want to use my own images so i changed the first line (favorites), but when i setting it, the image is starting in the middle, and always stays a small place for title,even if it's empty.
How can I controll the image possition inside those items? and disable the empty title place?

It's a fairly old question but even old questions need love :)
So if you're still having this problem you can use the UIViewControllers tab bar item image insets: tabBarItem.imageInsets.
You set this on view controllers which you will assign to viewControllers property of the tab bar controller.
Here is a swift version of a subclassed tab bar controller which will always ensure all images are aligned a bit lower.
override func setViewControllers(viewControllers: [AnyObject], animated: Bool) {
super.setViewControllers(viewControllers, animated: animated)
let array = viewControllers as! [UIViewController]
for controller in array {
controller.tabBarItem.imageInsets = UIEdgeInsetsMake(5, 0, -5, 0)
}
}

Related

UITabBarController selected item

I have UITabBarController and push on two views. I want the first view to be the default and the button to be in the "selected" state when it loads.
My problem is the tabBarItem does not have the selected background when it loads. I have to tap on it to show the selected. I'm also using custom images for the tab bar items as well and have them being configured in each view that gets added to the tabBarController.
I'm using this to set the selected item:
_tabBarController.selectedViewController = [_tabBarController.viewControllers objectAtIndex:0];
The UITabBarItem gets created in each view that I add to the tabBarController:
-(UITabBarItem *)tabBarItem
{
return [[UITabBarItem alloc] initWithTitle:#"" image:[UIImage imageNamed:#"tab_select_indicator_map.png"] tag:0];
}
How can I also have the tabBarItem show the selected state?
Use following code of display selected tabBarItem when your tabBar is loaded.
[_tabBarController setSelectedIndex:0]; // your can set index as per your requirement.
Eited:
Make sure that you created your tabBarItem such like
UITabBarItem* myTestingItem = [[UITabBarItem alloc] init];
[myTestingItem setFinishedSelectedImage: [UIImage imageNamed: #"btnTabItem-SelectedImage.png"]
withFinishedUnselectedImage: [UIImage imageNamed: #"btnTabItem.png"]];

Setting "More Navigation Controller's" titleView text

I'm surprised that not "more" has been asked about this :-)
My app is a standard tab bar controller with multiple sections. Each section (tab) contains a navigation controller that controls a couple of view controllers (your basic tableview + detailview type of setup). Now that I've added a 6th tab, iOS creates the default "More" tab that controls the final two tabs. I need to eliminate the "More" text in the middle of the navigation bar (Note: Not the button text, nor the title of the tab itself), and apply a custom background image to the navigation bar.
Note: This question is about customizing the "More" navigation bar - I've successfully modified the background image and titleView text on all of the non-iOS created navigation bars.
In my app delegate, the app is put together thusly:
Create View Controllers:
ViewController1 *vc1 = [ViewController1 alloc] initWithNibName#"View1" bundle:nil];
vc1.title = #"VC1";
vc1.tabBarImage.image = [UIImage imageNamed:#"image1.png"];
Repeat the above routine 5 more times for view controllers vc2 through vc6.
Create the individual navigation controllers:
UINavigationController *nc1 = [UINavigationController alloc] initWithRootViewController:vc1];
Repeat 5 more times for nav controllers nc2 - nc6.
Add Nav Controllers to Tab Bar Controller
self.tabBarController.viewControllers = [NSArray arrayWithObjects: vc1, vc2, vc3, vc4, vc5, vc6, nil];
All of the code above works perfectly. No issues.
I then add a custom background image to the More navigation controller thusly:
if (self.tabBarController.moreNavigationController){
if ([self.tabBarController.moreNavigationController.navigationBar respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)] ) {
UIImage *image = [UIImage imageNamed:#"navlogo.png"];
[self.tabBarController.moreNavigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
} else {
UINavigationBar *navbar = self.tabBarController.moreNavigationController.navigationBar;
UIImage *headerImg = [UIImage imageNamed:#"navlogo.png"];
[navbar setBackgroundImage:headerImg forBarMetrics:UIBarMetricsDefault];
}
}
This too works just fine. No issues
Since my custom background contains the client's logo dead center, I need to remove the text of the titleView that by default reads "More". Note, I'm not talking about the text of the Navigation BUTTON, but the label in the middle of the navigation bar.
Logically, one would assume that this would work:
UILabel *label = [[UILabel alloc] init];
label.text = #"";
self.tabBarController.moreNavigationController.navigationItem.titleView = label;
...because I do this in all of individual view controllers, substituting self.navigationItem.titleView for self.tabBarController.moreNavigationController, etc.
But this doesn't work! I can successfully change both the background image and the titleView text on all of my navigation controllers with this exact same code (again, substituting self.navigationController.navigationItem for the moreNavController stuff...). However, in the app delegate, I can only set the background image, but not the titleView of the More nav controller.
Any solutions would be greatly appreciated.
VB
Turns out, my original code was correct, just in the wrong place.
UILabel *label = [[UILabel alloc] init];
label.text = #"";
self.tabBarController.moreNavigationController.navigationBar.topItem.titleView = label;
However, I was previously executing this before I added the tabBarController as my rootViewController
The correct order is:
self.window.rootViewController = self.tabBarController;
UILabel *label = [[UILabel alloc] init];
label.text = #"";
self.tabBarController.moreNavigationController.navigationBar.topItem.titleView = label;
Posting Swift5 version as it took me quite some time to make it work properly
moreNavigationController.viewControllers[0].tabBarItem = UITabBarItem(title: "My Title", image: UIImage(named: "MoreTab")!, tag: 1111)
moreNavigationController.navigationBar.topItem!.title = "My Title"
Please note that changing moreNavigationController.tabBarItem doesn't work quite well. I do this in viewDidLoad() of a class which extends UITabBarController
E.g., in application:didFinishLaunchingWithOptions: of the Tab Controller iOS Template
// Override point for customization after application launch.
UITabBarController *tabBarController = (UITabBarController *)(self.window.rootViewController);
UINavigationController *moreNavigationController = tabBarController.moreNavigationController;
moreNavigationController.navigationBar.topItem.title = #"";
This changes the navigation bar title, but leaves the tab label title as "More".
I found one
Swift 2.2
Put this in didFinishLaunchingWithOptions
tabBarCtr.moreNavigationController.delegate = self
tabBarController.moreNavigationController.viewControllers.first?.title = ""
Implement this delegate method
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool)
{
navigationController.navigationBar.topItem?.rightBarButtonItems = nil
navigationController.viewControllers.first?.title = ""
}
This will also remove the edit button on top of more navigation controller navigation bar.
This might not be applicable to everyone on the thread but for me... I had a tabBarController with > 5 items... I needed to set the title on the automatically generated moreNavigationController... it was as simple as specifying self.title=#"title" in the viewDidLoad method of the target detailviewcontroller.
You can change the title inside the viewDidLoad function
self.title = #""

Only image as UITabBarItem

I would only like to have an icon as the UITabBarItem and not the text underneath and I was wondering if this was possible, if so, how? TIA
REMOVE THE TITLE
The easy way with inspector
Select your TabbarItem
In Title Position change to Custom Offset
Set vertical to 100
Done
Fix IMAGE
Adjuste the image
Select your TabbarItem
define your Top and Bottom
If you use story board, maybe you can use Image Inset from size inspector of bar item and set title to empty at the same time:
if you just set the image and pass nil to title, the image will be displayed at the top level of the UITabBar item. You have to set the position also.
int offset = 7;
UIEdgeInsets imageInset = UIEdgeInsetsMake(offset, 0, -offset, 0);
After you set icon image for TabBarItem, you set the property value to change the image position, doing:
uiViewController.tabBarItem.imageInsets = imageInset;
Setting the item's title to nil is often insufficient, because if you set the view controller's title it will set the title of the tabbar item also.
Instead, do this:
tabbarItem.titlePositionAdjustment = UIOffsetMake(0.f, 50.f);
You can use this Swift extension to define a new method tabBarItemShowingOnlyImage(), which will return any UITabBarItem modified to show only the image:
// helper for creating an image-only UITabBarItem
extension UITabBarItem {
func tabBarItemShowingOnlyImage() -> UITabBarItem {
// offset to center
self.imageInsets = UIEdgeInsets(top:6,left:0,bottom:-6,right:0)
// displace to hide
self.setTitlePositionAdjustment(UIOffset(horizontal:0,vertical:30000))
return self
}
}
This extension builds from the advice offered in other comments.
It hides the title by displacing it, rather than setting it to nil, because sometimes other objects like the view controller itself will set the title to some value after the tab bar item is initialized. It centers the image by using the imageInsets to offset it by 6pt, a value I get just from eyeballing it on an iPhone 6 running iOS8.3.
I imagine that other devices and layout configurations might require a different offset correction, so a general solution would probably have to be more complex.
I know its been quite some time. But I might have a solution for this problem.
#ThiagoPires answer is useful only if the image is big enough to cover the title. In case if it isn't, then the title will be visible under the image.
I think that the easiest way to accomplish this, is by setting the title of the tabBarItem to "" in your view controllers code.
It is important to know that every time you change your view controllers title, the tabbaritem's title will be updated too. You could go fancy using KVO to observe the title's change and set "" to the tabbaritem title accordingly. But if you don't change it in many places in your code, you could just set it right in the place you change the ViewController's title.
Here is an example in swift:
override func viewDidLoad() {
super.viewDidLoad()
self.title = "View controller's Title"
self.tabBarItem.title = ""
}
That's it. I hope that this could help.
Relevant docs (highlighting mine):
initWithTitle:image:tag:
Creates and returns a new item using the specified properties.
- (id)initWithTitle:(NSString *)title image:(UIImage *)image tag:(NSInteger)tag
Parameters
title: The item’s title. If nil, a title is not displayed.
image: The item’s image. If nil, an image is not displayed.
The images displayed on the tab bar are derived from this image. If this image is too large to fit on the tab bar, it is clipped to fit. The size of a tab bar image is typically 30 x 30 points. The alpha values in the source image are used to create the unselected and selected images—opaque values are ignored.
tag: The receiver’s tag, an integer that you can use to identify bar item objects in your application.
Return Value: Newly initialized item with the specified properties.
Try with below code:
UIViewController *viewController1=[[RootViewController alloc]initWithNibName:#"RootViewController" bundle:nil];
UIViewController *viewController2=[[SecondViewCtr alloc]initWithNibName:#"SecondViewCtr" bundle:nil];
UIViewController *viewController3=[[ThirdViewCtr alloc]initWithNibName:#"ThirdViewCtr" bundle:nil];
UIViewController *viewController4=[[FourthVIewCtr alloc]initWithNibName:#"FourthVIewCtr" bundle:nil];
UIViewController *viewController5=[[FIfthViewCtr alloc]initWithNibName:#"FIfthViewCtr" bundle:nil];
UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
UINavigationController *nav2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
UINavigationController *nav3 = [[UINavigationController alloc] initWithRootViewController:viewController3];
UINavigationController *nav4 = [[UINavigationController alloc] initWithRootViewController:viewController4];
UINavigationController *nav5 = [[UINavigationController alloc] initWithRootViewController:viewController5];
peekArray = [[NSMutableArray alloc] init];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:nav1, nav2,nav3,nav4,nav5, nil];
UITabBar *tabBar = _tabBarController.tabBar;
UITabBarItem *tabBarItem1 = [tabBar.items objectAtIndex:0];
UITabBarItem *tabBarItem2 = [tabBar.items objectAtIndex:1];
UITabBarItem *tabBarItem3 = [tabBar.items objectAtIndex:2];
UITabBarItem *tabBarItem4 = [tabBar.items objectAtIndex:3];
UITabBarItem *tabBarItem5 = [tabBar.items objectAtIndex:4];
[tabBarItem1 setFinishedSelectedImage:[UIImage imageNamed:#"home123.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"home_112.png"]];
[tabBarItem2 setFinishedSelectedImage:[UIImage imageNamed:#"gift123.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"gift_112.png"]];
[tabBarItem3 setFinishedSelectedImage:[UIImage imageNamed:#"cam12.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"cam_112.png"]];
[tabBarItem4 setFinishedSelectedImage:[UIImage imageNamed:#"message12.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"message_112.png"]];
[tabBarItem5 setFinishedSelectedImage:[UIImage imageNamed:#"people12.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"people_112.png"]];
[self.tabBarController setSelectedIndex:0];
self.window.rootViewController = self.tabBarController;
like this
UITabBarItem * personalBarItem = [[UITabBarItem alloc] init];
[personalBarItem setFinishedSelectedImage:[UIImage imageNamed:#"personal_click"] withFinishedUnselectedImage:[UIImage imageNamed:#"personal"]];

How can I place a header image fixed at the top of my Tab Application?

I want to create a Tab Application with a header image that is always present, no matter what Tab Item is active.
The example would be Foursquare:
I want to be able to place buttons and have different information displayed on that header.
Is that a simple Navigation Bar or something else?
Usually, for each tab is associated a viewController. You can notice it in the boilerplate which xcode creates when you choose "Tabbed Application".
Then, in each viewDidLoad or in the init of each viewcontroller you can set:
self.navigationItem.titleView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.png"]];
Then just change self.navigationItem.leftBarButtonItem and self.navigationItem.rightBarButtonItem with your controls on each viewController.
Edit:
In the appDelegate (in the didFinishLaunchingWithOptions method) you've to set something like this if you want use the navigationcontrollers:
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UINavigationController *myNav1=[[UINavigationController alloc] initWithRootViewController:viewController1];
UINavigationController *myNav2=[[UINavigationController alloc] initWithRootViewController:viewController2];
UIImage *navBackgroundImg = [UIImage imageNamed:#"bg_navBar.png"];
UIImage *tabBackgroundImg = [UIImage imageNamed:#"bg_tabBar.png"];
[myNav1.navigationBar setBackgroundImage:navBackgroundImg forBarMetrics:UIBarMetricsDefault];//iOS 5 only
[myNav2.navigationBar setBackgroundImage:navBackgroundImg forBarMetrics:UIBarMetricsDefault];//iOS 5 only
[[UITabBar appearance] setBackgroundImage:tabBackgroundImg];//iOS 5 only
self.tabBarController.viewControllers = [NSArray arrayWithObjects:myNav1, myNav2, nil];
self.window.rootViewController = self.tabBarController;
Looks like a simple navigation bar, but they aren't exactly simple. You need to place/create a NavigationItem on the bar (after placing/creating the bar itself) and then set the titleView to a custom view with your image. According to the documentation the left bar button (close in your first screen) has to be nil or else the titleView is ignored. Though you can place buttons in this custom view for left buttons.
I found out the easiest thing to do is to write:
- (void)viewDidLoad
{
[[UINavigationBar appearance] setBackgroundImage:
[UIImage imageNamed:#"UINavigationBar.png"] forBarMetrics:UIBarMetricsDefault];
}
At my MainViewController, and all Navigation bars that get created on each view controller gets configured like that.

How to scale a TabBarItem Image

I want to add a UITabBar in my UIViewController, I don't want to use UITabBarController because I need to push this view controller into a navigation controller.
Everything is fine except that my images for UITabBarItem is not scale to fit the item size to be displayed properly.
How to fix this problem?
Here is some code:
UITabBar *myTabBar = [[UITabBar alloc] initWithFrame:CGRectMake(0.0, barHeight, screenBounds.size.width, 50.0)];
myTabBar.opaque = YES;
UITabBarItem *barItem1 = [[UITabBarItem alloc] initWithTitle:#"title1" image:[UIImage imageNamed:#"icon1.png"] tag:1];
UITabBarItem *barItem2 = [[UITabBarItem alloc] initWithTitle:#"title2" image:[UIImage imageNamed:#"icon2.png"] tag:2];
UITabBarItem *barItem3 = [[UITabBarItem alloc] initWithTitle:#"title3" image:[UIImage imageNamed:#"icon3.png"] tag:3];
UITabBarItem *barItem4 = [[UITabBarItem alloc] initWithTitle:#"title4" image:[UIImage imageNamed:#"icon4.png"] tag:4];
NSArray *tbItems = [NSArray arrayWithObjects:barItem1, barItem2, barItem3, barItem4, nil];
myTabBar.items = tbItems;
You should save your TabBar images as 42x42. Then, in the name of the file ad the #2x directive.
i.e. icon1#2x.png
We do this so that the icon is loaded at 42x42 pixels on the iPhone 4/iPod Touch 4G, but scaled down to 21x21 for older devices.
This is going to save you a lot of time. Also note that the UITabBar only cares about the alpha channel of the image. So single color images are a good idea. This will save space.
I feel that you should be using a UIToolBar or UISegmentedControl and not a UITabBar.
UITabBar's should usually be used with a UITabBarController to manage it and should be used to switch app "mode" as Apple puts it. This means the TabBarController should be the rootViewController (an exception would be if you add a login view before the app starts up as a tab bar app).
this thread might also help