Changing width of UITabbarItems and margins between them in iPad app - iphone

Is it possible to change the width of UITabbarItem in UITabbar and margins between each UITabbarItem for iPad Application?
The problem is that standard margins are too large for my layout - client want tabs to be more compact :/
Or should I mess with UIToolbar to achieve this goal?

For Tabbar item width :
[[UITabBar appearance] setItemWidth:self.window.frame.size.width/NUMBER_OF_ITEMS];
For tabbar frame :
[self.tabBar setFrame:rectFrame];

I have solved just the same problem it this way:
my goal was to customize tab bar by using images, that were sent by the designer for me.
I have attached the .png files for the project, initialized the correspondent variables of type UIImage* and used UITabBarItem function setFinishedSelectedImage: withFinishedUnselectedImage: to set the images for active / inactive state of UITabbarItem:
UIImage * left_active, *left_inactive, *center_active, *center_inactive, *right_active, *right_inactive;
left_active = [UIImage imageNamed:#"left_active_img"];
...
[self.leftTabBarItem setFinishedSelectedImage:left_active withFinishedUnselectedImage:left_inactive];
[self.centerTabBarItem setFinishedSelectedImage:center_active withFinishedUnselectedImage:center_inactive];
[self.rightTabBarItem setFinishedSelectedImage:right_active withFinishedUnselectedImage:right_inactive];
But the customized tabbarItems were smaller, than the designer's images and were allocated at the center of the screen one upon other:
2) To fix this I have ADDED ADDITIONAL UITABBARITEMS - at the left and at the right corner of the initial ones
3) the were created the correspondent outlets for the UITabBarItems:
.h-file:
#property (nonatomic, retain) IBOutlet UITabBar * tabBar;
// THE INTIAL items
#property (nonatomic, retain) IBOutlet UITabBarItem * leftTabBarItem;
#property (nonatomic, retain) IBOutlet UITabBarItem * centerTabBarItem;
#property (nonatomic, retain) IBOutlet UITabBarItem * rightTabBarItem;
// THE ADDITIONAL items
#property (nonatomic, retain) IBOutlet UITabBarItem * left_1;
#property (nonatomic, retain) IBOutlet UITabBarItem * left_2;
#property (nonatomic, retain) IBOutlet UITabBarItem * center_1;
#property (nonatomic, retain) IBOutlet UITabBarItem * center_2;
#property (nonatomic, retain) IBOutlet UITabBarItem * right_1;
#property (nonatomic, retain) IBOutlet UITabBarItem * right_2;
then attached the Outlets to the UITabBarItems in the order listed below:
left_1
leftTabBarItem
left_2
center_1
centerTabBarItem
center_2
right_1
rightTabBarItem
right_2
and CORRECTED THE UITabbarDelegate METHOD in the delegating class to switch ONLY beet wen the visible items
.m-file:
#pragma mark - UITabbarDelegate
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{
if (item == self.leftTabBarItem)
{
NSLog(#"0"); // first visible item selected
} else if (item == self.centerTabBarItem)
{
NSLog(#"1"); // second visible item selected
} else if (item == self.rightTabBarItem)
{
NSLog(#"2"); // third visible item selected
} else if (item == self.left_1){
[self.tabBar setSelectedItem: self.leftTabBarItem];
} else if (item == self.left_2){
[self.tabBar setSelectedItem: self.leftTabBarItem];
} else if (item == self.center_1){
[self.tabBar setSelectedItem: self.centerTabBarItem];
}else if (item == self.center_2){
[self.tabBar setSelectedItem: self.centerTabBarItem];
}else if (item == self.right_1){
[self.tabBar setSelectedItem: self.rightTabBarItem];
} else if (item == self.right_2){
[self.tabBar setSelectedItem: self.rightTabBarItem];
}
}
Now everything looks and works properly.
You can use the same steps to customize the size and interspaces between UITabBarItems by adding additional items and correcting delegate methods.

I don't think it is possible. You can create a custom tab bar. Also messing around with default UItabbar might cause rejection during App approval process.

You can change the spacing of the tab bar items by subclassing UITabBar and overriding its layoutSubviews method. You will find all tab bar buttons in the self.subViews array. Their class is the non-public UITabBarButton but they inherit from UIControl so you can identify all tab bar buttons checking if they are kind of UIControl class. Then all you need is to change the frame of the tab bar buttons.

You can use setSelectionIndicatorImage to make your tab more compact.
The UITabBarItem width in iPad will match the selectionIndicatorImage's width
in AppDelegate.m
[[UITabBar appearance] setItemWidth:self.window.frame.size.width/NUMBER_OF_YOUR_TAB];
[[UITabBar appearance] setItemSpacing:0];
[[UITabBar appearance] setSelectionIndicatorImage:[self imageFromColor:[UIColor clearColor] forSize:CGSizeMake(self.window.frame.size.width/NUMBER_OF_YOUR_TAB, 10) withCornerRadius:0]];
you can use below code to create a image programmatically
- (UIImage *)imageFromColor:(UIColor *)color forSize:(CGSize)size withCornerRadius:(CGFloat)radius
{
CGRect rect = CGRectMake(0, 0, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContext(size);
[[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius] addClip];
// Draw your image
[image drawInRect:rect];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

No subclassing is needed.
tabBarController.tabBar.itemPositioning = .centered
tabBarController.tabBar.itemWidth = 40
tabBarController.tabBar.itemSpacing = 38

You cannot change the width of the the UITabBarItem, and you cannot do this even after subclassing the UITabBarItem. Apple has certain restrictions in the way they want the developers to implement the applications.
You will need to use a UIToolBar for this, and my best bet is for you to go to github and as there a lot of sample applications which use a scrollable UIToolBar at the bottom instead of the UITabBar.

Related

UITabBarController image iOS 5

I created a UITabBarController with storyboard for iOS5. I don't have the UITabBar declared in my ViewController and I can't set background image for tab bar.
UIImage *tabBackground = [[UIImage imageNamed:#"tabBarBackground.jpg"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
// Set background for all UITabBars
[[UITabBar appearance] setBackgroundImage:tabBackground];
// Set background for only this UITabBar
[[tabBarController tabBar] setBackgroundImage:tabBackground];
You'll need to designate tabBarController as an IBOutlet property
#property (nonatomic, strong) IBOutlet UITabBarController *tabBarController;
Then wire them up in the Connections inspector in Interface Builder, and you'll be able to use your code as shown.

UITextView not word wrapping

I'm new to IOS development, and I'm just trying to get my head around all the views. At first I have a UITextField which is one line and I wanted it to wrap. I was told to implement a UITextView instead - and that worked! I then had many lines of wrapped text.
The next thing I wanted to do was have horizontally scrolling pages. I downloaded apple's page control example. In it many pages are created with a little text label. I altered this to contain a very long string, and replaced the UILabel type with a UITextView. However, it's not word wrapping! The cause could be anything an I have absolutely no idea what it might be. Perhaps it's inheriting some setting from something?
Any help would be much appreciated.
Edit - here is where the views are created:
- (void)loadScrollViewWithPage:(int)page
{
if (page < 0)
return;
if (page >= kNumberOfPages)
return;
MyViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{
controller = [[MyViewController alloc] initWithPageNumber:page];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
if (controller.view.superview == nil)
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
NSDictionary *numberItem = [self.contentList objectAtIndex:page];
controller.numberTitle.text = [numberItem valueForKey:NameKey];
}
}
and this is the MyViewController header:
#import <UIKit/UIKit.h>
#interface MyViewController : UIViewController
{
UILabel *pageNumberLabel;
int pageNumber;
UITextView *numberTitle;
UIImageView *numberImage;
}
#property (nonatomic, retain) IBOutlet UILabel *pageNumberLabel;
#property (nonatomic, retain) IBOutlet UITextView *numberTitle;
#property (nonatomic, retain) IBOutlet UIImageView *numberImage;
- (id)initWithPageNumber:(int)page;
#end
Check the frame of the UITextView. It's possible if you just swapped UITextView with UILabel that the frame is not large enough. Change the frame to have a larger height. Also, set the background color to a bright color so you know can see how large it is on the screen.
Even though everything in the program was changed, the xib file still contained a UILabel which is what was displaying the text.

hide and show intermittent uilabel and uinavigation title?

Hello to all people!!
I need to made one uilabel thats shows and hide intermittently likes information message in the main view...
I need the same in the title of the navigation bar... Is this possible?
any suggestions please...
Sure.
Supposing you have:
#property (nonatomic, retain) IBOutlet UILabel * myLabel;
You can easily:
[self.myLabel setHidden:YES];
or
self.myLabel.hidden = YES;
or
[self.myLabel setHidden:NO];
or
self.myLabel.hidden = NO;
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html

Can I have UIToolbar Bar Button Item States

Is there an easy way to have an on state and an off state for the UIBarButtonItems, with different images for each?
Thanks
There isn't a built-in way, but I can think of a few approaches (depending on your needs):
Bind the button to a method that toggles whatever the button is meant to toggle, and then changes the button's image property accordingly
Create your own subclass of UIBarButtonItem that looks something like this:
#interface ToggleBarButtonItem : UIBarButtonItem {
BOOL _state;
UIImage * onImage;
UIImage * offImage;
}
- (BOOL)toggleState;
#property (nonatomic, retain) UIImage * onImage;
#property (nonatomic, retain) UIImage * offImage;
#end
#implementation ToggleBarButtonItem
- (BOOL)toggleState {
if (_state) {
// Switch to Off state
self.image = offImage;
}
else {
// Switch to On state
self.image = onImage;
}
return _state = !_state;
}
#end

Custom colors in UITabBar

Is it possible to use custom colors and background images in a UITabBar? I realize that Apple would like everyone to use the same blue and gray tab bars, but is there any way to customize this?
Second, even I were to create my own TabBar-like view controller, along with custom images, would this violate Apple's Human Interface Guidelines?
I found an answer to this at Silent Mac Design.
I implemented this way:
First make a subclass of UITabBarContoller
// CustomUITabBarController.h
#import <UIKit/UIKit.h>
#interface CustomUITabBarController: UITabBarController {
IBOutlet UITabBar *tabBar1;
}
#property(nonatomic, retain) UITabBar *tabBar1;
#end
 
// CustomUITabBarController.m
#import "CustomUITabBarController.h"
#implementation CustomUITabBarController
#synthesize tabBar1;
- (void)viewDidLoad {
[super viewDidLoad];
CGRect frame = CGRectMake(0.0, 0, self.view.bounds.size.width, 48);
UIView *v = [[UIView alloc] initWithFrame:frame];
[v setBackgroundColor:[[UIColor alloc] initWithRed:1.0
green:0.0
blue:0.0
alpha:0.1]];
[tabBar1 insertSubview:v atIndex:0];
[v release];
}
#end
And in your Nib file replace the class of your TabBar Controller with CustomUITabBarController.
FYI, from iOS 5 onwards you can customize various aspects of the UITabBar, including setting its background image using the backgroundImage property.
The new UITabBar "Customizing Appearance" properties in iOS 5 are:
backgroundImage
selectedImageTintColor
selectionIndicatorImage
tintColor
Given that Apple have introduced these methods in iOS 5, then it's possible they may be more sympathetic to attempts to customize the UITabBar for earlier OSes. This website says the Twitter app uses a custom tab bar, so that might be more reason that Apple would let such an app into the App Store, it's no guarantee though!
Use Following images ( Assuming, tabBar is having 5 Tabs as follows )
Create a new project using - "TabBar Application" template & Place following code.
Contents of AppDel.h File.
#import <UIKit/UIKit.h>
#interface cTabBarAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#property (nonatomic, retain) IBOutlet UIImageView *imgV;
#end
Contents of AppDel.m File.
#import "cTabBarAppDelegate.h"
#implementation cTabBarAppDelegate
#synthesize window=_window;
#synthesize tabBarController=_tabBarController;
#synthesize imgV = _imgV;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.tabBarController.delegate=self;
self.imgV.frame=CGRectMake(0, 425, 320, 55);
[self.tabBarController.view addSubview:self.imgV];
self.tabBarController.selectedIndex=0;
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
NSUInteger index=[[tabBarController viewControllers] indexOfObject:viewController];
switch (index) {
case 0:
self.imgV.image=[UIImage imageNamed:#"tBar1.png"];
break;
case 1:
self.imgV.image=[UIImage imageNamed:#"tBar2.png"];
break;
case 2:
self.imgV.image=[UIImage imageNamed:#"tBar3.png"];
break;
case 3:
self.imgV.image=[UIImage imageNamed:#"tBar4.png"];
break;
case 4:
self.imgV.image=[UIImage imageNamed:#"tBar5.png"];
break;
default:
break;
}
return YES;
}
At the beginning of ***ViewController.m add the following might help set background image of UITabBar.
#implementation UITabBar (CustomImage)
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed: #"background.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
If you want to use custom colors for the icons (and not just the background) instead of the default gray and blue, do it like this: http://blog.theanalogguy.be/2010/10/06/custom-colored-uitabbar-icons/
Basically, you need to create complete tabbar images (background and icons and text) for each selected tab and set your UITabBarItems to no icon and no title and insert the image into the tabbar as an UIImageView in viewWillAppear:
And Apple won't mind since we are not using any private APIs.
Since iOS 7.0, you can use -[UIImage imageWithRenderingMode:] with UIImageRenderingModeAlwaysOriginal to preserve colors:
// Preserve the colors of the tabs.
UITabBarController *controller = (UITabBarController *)((UIWindow *)[UIApplication sharedApplication].windows[0]).rootViewController;
NSArray *onIcons = #[ #"tab1-on", #"tab2-on", #"tab3-on" ];
NSArray *offIcons = #[ #"tab1-off", #"tab2-off", #"tab3-off" ];
NSArray *items = controller.tabBar.items;
for (NSUInteger i = 0; i < items.count; ++i) {
UITabBarItem *item = items[i];
item.image = [[UIImage imageNamed:offIcons[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
item.selectedImage = [[UIImage imageNamed:onIcons[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
Works like a charm.
In AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UITabBar appearance] setSelectedImageTintColor:[UIColor redColor]];
return YES;
}
As far as the UITabBar class is concerned, the icons in the bar are limited to the colours: blue for selected and grey for unselected. This is because the tab bar only uses the alpha value from the icons you supply to create the image on the bar.
The bar itself is limited to being black, as far as I can remember. I've not seen anything like the 'tint' property on UINavigationBar in the docs.
I guess you could go ahead and create your own tab bar style class and do what you want with it, but I have absolutely no idea how that fits in with Apple's HIG, or whether or not they'd challenge it during the review process.
In my experience, Apple reviewers only rejected my app if I didn't use THEIR UI elements according to the HIG. They might have a different view when it's your own UI elements you're playing with.
Here's the document that says we can't change pressed or selected appearance with our icons.
https://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/MobileHIG/IconsImages/IconsImages.html#//apple_ref/doc/uid/TP40006556-CH14-SW1
It's under the heading
Icons for Navigation Bars, Toolbars, and Tab Bars
Its possible without adding any subView.
In the class where you define the tab bar set the property of the
tabBarItem to ->>
UITabBarItem *tabBarItem1 = [[self.tabBar.tabBar items] objectAtIndex:0];
[tabBarItem1 setFinishedSelectedImage:[UIImage imageNamed:#"campaigns_hover.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"campaigns.png"]];
Its a property of tabBarItem and u can change the default blue image to a custom image.
campaigns_hover.png is the selected custom image AND
campaigns.png is the custom image when not selected...
Enjoy the secret.. :)
The below code helps you to add custom colors with RGB values to ur tabBar.
self.tabBarController.tabBar.tintColor = [[UIColor alloc] initWithRed:0.00
green:0.62
blue:0.93
alpha:1.0];
You can do that without -insertSubview:atIndex, because a new UIView is not needed. You can apply a theme using QuartzCore on each view (UITabBar and it's subviews). So the UITabBar's background is added as I've described here.
Now we must apply the image on each UITabBarItem as it's background:
// UITabBar+CustomItem.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface UITabBar (CustomItem)
-(void)setSelectedItemBackground:(UIImage *)backgroundImage;
#end
Now the .m file:
// UITabBar+CustomItem.m
#implementation UITabBar (CustomItem)
#define kItemViewTag 445533 // <-- casual number
#define kItemViewOldTag 445599 // <-- casual number different from the above
-(void)setSelectedItemBackground:(UIImage *)backgroundImage {
UIView *oldView = [self viewWithTag:kImageViewItemTag];
oldView.layer.contents = nil; // <-- remove the previous background
oldView.tag = kItemViewOldTag; // <-- this will avoid problems
NSUInteger index = [self.items indexOfObject:self.selectedItem];
UIView *buttonView = [self.subviews objectAtIndex:index];
buttonView.tag = kItemViewTag;
buttonView.layer.contents = (id)backgroundImage.CGImage; // <-- add
// the new background
}
#end
You can also change the color of the selected images, as someone made here. But what I'm wondering is: can I change the color of the selected label? The answer is yes, as described below (the following works on ios 3.x/4.x, not iOS5+):
#implementation UITabBar (Custom)
#define kSelectedLabel 334499 // <-- casual number
-(void)changeCurrentSelectedLabelColor:(UIColor *)color {
UIView *labelOldView = [self viewWithTag:kSelectedLabel];
[labelOldView removeFromSuperview];
NSString *selectedText = self.selectedItem.title;
for(UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class])
isEqualToString:#"UITabBarButton"]) {
for(UIView *itemSubview in subview.subviews) {
if ([itemSubview isKindOfClass:[UILabel class]]) {
UILabel *itemLabel = (UILabel *)itemSubview;
if([itemLabel.text isEqualToString:selectedText]) {
UILabel *selectedLabel = [[UILabel alloc]
initWithFrame:itemLabel.bounds];
selectedLabel.text = itemLabel.text;
selectedLabel.textColor = color;
selectedLabel.font = itemLabel.font;
selectedLabel.tag = kSelectedLabel;
selectedLabel.backgroundColor = [UIColor clearColor];
[itemSubview addSubview:selectedLabel];
[selectedLabel release];
}
}
}
}
}
}
#end