It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Does anyone know how to style their uitabbar like Apple in Music and Clock apps on the iPad?
I have been searching the web over but I can't find much out there.
Thanks
Edit:
Rephrasing, I'm trying to understand how to go about setting this up. I've been trying using uitabbarcontroller but I wasn't sure if this was a manipulated style of uitabbaritems or if it was using segmented controls. It seems to be a common view in Apple's new apps, but I wasn't sure how much customization was needed to achieve the effect. If I wanted to have two unique views selectable in a similar fashion to Apple's Music and Clock apps, would I approach as follows:
UIViewController (root)
UIToolbar
Segmented Control
Button 1
Loads ViewController1
Button 2
Loads ViewController2
That is a UISegmentedControl. You can style its appearance using the following methods:
/* Default tintColor is nil. Only used if style is UISegmentedControlStyleBar or UISegmentedControlStyleBezeled
*/
#property(nonatomic,retain) UIColor *tintColor UI_APPEARANCE_SELECTOR;
/* If backgroundImage is an image returned from -[UIImage resizableImageWithCapInsets:] the cap widths will be calculated from that information, otherwise, the cap width will be calculated by subtracting one from the image's width then dividing by 2. The cap widths will also be used as the margins for text placement. To adjust the margin use the margin adjustment methods.
In general, you should specify a value for the normal state to be used by other states which don't have a custom value set.
Similarly, when a property is dependent on the bar metrics (on the iPhone in landscape orientation, bars have a different height from standard), be sure to specify a value for UIBarMetricsDefault.
In the case of the segmented control, appearance properties for UIBarMetricsLandscapePhone are only respected for segmented controls in the smaller navigation and toolbars that are used in landscape orientation on the iPhone.
*/
- (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
- (UIImage *)backgroundImageForState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
/* To customize the segmented control appearance you will need to provide divider images to go between two unselected segments (leftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal), selected on the left and unselected on the right (leftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal), and unselected on the left and selected on the right (leftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected).
*/
- (void)setDividerImage:(UIImage *)dividerImage forLeftSegmentState:(UIControlState)leftState rightSegmentState:(UIControlState)rightState barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
- (UIImage *)dividerImageForLeftSegmentState:(UIControlState)leftState rightSegmentState:(UIControlState)rightState barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
/* You may specify the font, text color, text shadow color, and text shadow offset for the title in the text attributes dictionary, using the keys found in UIStringDrawing.h.
*/
- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
- (NSDictionary *)titleTextAttributesForState:(UIControlState)state NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
/* For adjusting the position of a title or image within the given segment of a segmented control.
*/
- (void)setContentPositionAdjustment:(UIOffset)adjustment forSegmentType:(UISegmentedControlSegment)leftCenterRightOrAlone barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
- (UIOffset)contentPositionAdjustmentForSegmentType:(UISegmentedControlSegment)leftCenterRightOrAlone barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
This example sets the background and the divider images for the different selection states (using the appearance proxy to change the appearance of all segmented controls):
UIImage *segmentSelected =
[[UIImage imageNamed:#"segcontrol_sel.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
UIImage *segmentUnselected =
[[UIImage imageNamed:#"segcontrol_uns.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
UIImage *segmentSelectedUnselected =
[UIImage imageNamed:#"segcontrol_sel-uns.png"];
UIImage *segUnselectedSelected =
[UIImage imageNamed:#"segcontrol_uns-sel.png"];
UIImage *segmentUnselectedUnselected =
[UIImage imageNamed:#"segcontrol_uns-uns.png"];
[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected
forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected
forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentUnselectedUnselected
forLeftSegmentState:UIControlStateNormal
rightSegmentState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected
forLeftSegmentState:UIControlStateSelected
rightSegmentState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance]
setDividerImage:segUnselectedSelected
forLeftSegmentState:UIControlStateNormal
rightSegmentState:UIControlStateSelected
barMetrics:UIBarMetricsDefault];
Related
I am develop in objective-C. I want to change the tab bar background like the following picture:
And the code is like the following:
UIImage *tabBarBackground = [UIImage imageNamed:#"tabbaritem_background.png"];
[[UITabBar appearance] setBackgroundImage:tabBarBackground];
But after setting the background image , the background is not at the correct place like the following:
The background image should be place at the bottom like the background in above picture.
Did I missing something ? Can someone help me ?
Thanks in advance.
I think is somewhere you go wrong, check if is this steps:
In the storyboard change the ViewController's background color for test.
Embed the ViewController in Tab Bar Controller
In the ViewController.m you can set the tabbar bacground color:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[UITabBar appearance] setBackgroundColor:[UIColor grayColor]]; // Here you can set the converted color form image, make sure the imageSize fit.
}
The result is below:
I think the method - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode you can try, because your backgroudimage's size is not equal to tabbar'size.
Try this method to change your image to a ScaleImage.
+(UIImage *)getScaleImageNamed:(NSString *)name{
UIImage *nomalImage = [UIImage imageNamed:name];
CGFloat hInset = floorf(nomalImage.size.width / 2);
CGFloat vInset = floorf(nomalImage.size.height / 2);
UIImage *res = [nomalImage resizableImageWithCapInsets:UIEdgeInsetsMake(vInset, hInset, vInset, hInset)];
return res;
}
Steps you may miss, hope that can help.
Make sure you have imported the background image (e.g. in Assets.xcassets)
Use resizableImageWithCapInsets: to resize the background image
Put the UIAppearance settings in AppDelegate.m:
[[UITabBar appearance] setBackgroundImage:[[UIImage imageNamed:#"tabbaritem_background.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)]];
iOS 7.0.
I need to make your design UITabBar. The picture (this link) shows how it looks now and how it should look. The difference is that:
1) The images on the buttons of some dirty color, and should be white
2) The selected item is highlighted in a little darker background color. Now he does not highlighted at all.
Here's how I define design in AppDelegate.m in application:didFinishLaunchingWithOptions
// Background image for TabBar
UIImage *backgroundDownImage = [UIImage imageNamed:#"background_320_49.png"];
// Mode UIImageResizingModeStretch
backgroundDownImage = [backgroundDownImage resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeStretch];
// Set background image for all UITabBar in application
[[UITabBar appearance] setBackgroundImage:backgroundDownImage];
// White color for TabBar buttons
[[UITabBar appearance] setTintColor:[UIColor whiteColor]];
// Special font for all UITabBarItem
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:#"Xnjslkpqqovrwqxfnmropbgqtzp" size:0], UITextAttributeFont, nil] forState:UIControlStateNormal];
I tried the 4 variants:
1) In the method - (id)initWithNibName old code setFinishedSelectedImage + withFinishedUnselectedImage
2) In the method - (id)initWithNibName new code setImage + SetSelectedImage
3) In the method - (void)viewDidLoad old code
4) In the method - (void)viewDidLoad new code
- (void)viewDidLoad
{
[super viewDidLoad];
// Variant 1
[self.tabBarItem setImage:[[UIImage imageNamed:#"Live.png"] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal]];
[self.tabBarItem setSelectedImage:[[UIImage imageNamed:#"Live.png"] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal]];
// Variant 2
//[self.tabBarItem setFinishedSelectedImage:[UIImage imageNamed:#"Live.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"Live.png"]];
[CommonUse showLiveVideoFromController:self];
}
In all cases, icons will be displayed. Method initWithNibName (options 1 and 2) no action at all on the color icon has not. Method viewDidLoad work both old and new code - but in a strange way. When you first run the application, only the first icon is white, and all the other gray. If you click on any other icon and then go back to the first, this icon becomes white (but only a picture! Text is still gray).
It turns out that the color of icons affects only method viewDidLoad but not entirely - something else is missing.
Maybe draw two sets of icons for Selected and NoSelected. That was in the icon and image and text description as graphic. But still remain two points: 1) When you first start the application, all the icons will be gray, and only the first will be white. 2) When you change the width of the screen, do not disperse if the buttons.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[self.tabBarItem setFinishedSelectedImage:[UIImage imageNamed:#"partners_hover.png"] withFinishedUnselectedImage:[UIImage imageNamed:#"partners_small.png"]];
}
return self;
}
To change a color for unselected items (icons) you can use UITabBar property unselectedItemTintColor
[UITabBar appearance].unselectedItemTintColor = [UIColor anyColor];
On my nav bar, I have a couple of rightBarButtonItems that have custom icons (the icon images are white, which worked well with the basic color scheme of iOS 6).
Under iOS 7, loading the images using initWithTitle (see code snippet 1) replaces the "white" color in the icon with the proper global tint (a specific color of dark blue in this case)
Code Snippet 1:
UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc] initWithTitle:#"" style:(UIBarButtonItemStyle) UIBarButtonSystemItemCancel target:(self) action:#selector(refreshList)];
refreshButton.image = [UIImage imageNamed:#"RefreshIcon.png"];
However, I needed to use initWithCustomView to overcome a weird change in behavior that was causing the icons to move out of view. The basic idea was to specifically set the size of the icons. initWithCustomView solved the sizing problem, but does not display the button images with the global tint, they are displayed in the color of the image (white). Code Snippet 2 shows how I am creating the button with initWithCustomView.
Code Snippet 2:
CGRect frameCustomButton2 = CGRectMake(0.0, 0.0, 18.0, 18.0);
UIButton *customButton2 = [[UIButton alloc] initWithFrame:frameCustomButton2];
[customButton2 setBackgroundImage:iconRefreshButton forState:UIControlStateNormal];
UIBarButtonItem *barCustomButton2 =[[UIBarButtonItem alloc] initWithCustomView:customButton2 ];
barCustomButton2.image = iconRefreshButton;
[customButton2 addTarget:self action:#selector(refreshList) forControlEvents:UIControlEventTouchUpInside];
All of this code is of course in (void)viewDidLoad. I have tried things like:
barCustomButton2.tintColor = [UIColor blackColor]; //doesn't work
or
[barButtonAppearance setTintColor:[UIColor blackColor]]; // doesn't work
and they do not override the white color of the image. It is almost as if the creation of the custom view takes place after the view looks at the global tint color?
How can I ensure the button icon takes on the global tint?
Thanks!
Just wanted to get this into a root comment to give better context to the "answer" checkmark, and give better formatting.
I was able to figure this one out! You can tell the image to always render as template, which will force it to take on the global tint color.
UIImage *iconRefreshButton = [UIImage imageNamed:#"MyIconFilename.png"];
iconRefreshButton = [iconRefreshButton imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
The default, if you don't set it, is "UIImageRenderingModeAutomatic" which means it will render as a template or original image based on context.
You'll either have to work around the issue you were having with the first code snippet, or you'll have to create a UIButton subclass that uses its image as a mask to show the tint color in drawRect:.
I'd recommend the first approach.
using this in AppDelegate.m for my custom NavBar:
UIImage *NavigationPortraitBackground = [[UIImage imageNamed:#"gradient_main"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UINavigationBar appearance] setBackgroundImage:NavigationPortraitBackground forBarMetrics:UIBarMetricsDefault];
UIImage *barBackBtnImg = [[UIImage imageNamed:#"btn_nav_default.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:barBackBtnImg forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
results in:
As you can see the button seems to be repeated. Button dimensions are 61x30. And the text is not centered.
If the text is shorter (e.g. Menu) the button image is cut off and if text is longer, then button is repeating.
Similar problem with buttons that have a smaller icon (30x30). The button shows fine but I can click in the button outside of the image :(
The root of your problem is that you are providing a resizeable image without UIEdgeInsets and without specifying the resizing style. The text on your UIBarButtonItem is actually centered! If you measure the distance on both sides of the text, you'll realize that it's the same.
If you look at the image you provide for the UIBarButtonItem:
[[UIImage imageNamed:#"btn_nav_default.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
You're telling iOS that #"btn_nav_default.png" is a resizeable image and that it should tile. It's basically taking copies of your image and placing them side by side until the full width is covered. If you look at UIImage's Documentation you'll see that the default behaviour for resizableImageWithCapInsets is to tile. You will want to call resizableImageWithCapInsets:resizingMode: and pass in UIImageResizingModeStretch for your resizing mode.
That being said, that won't be enough. What you'll see after that is that the entire image is stretched, completely destroying your nice rounded corners. You need to provide UIEdgeInsets that tell UIImage that "you cannot stretch this section". In this case, providing UIEdgeInsets of UIEdgeInsetsMake(0.0f, 10.0f, 0.0f, 10.0f) (or something similar) will work.
If you're not interested in the long explanation, copy paste this code (no guarantees that this compiles though...):
[[UIImage imageNamed:#"btn_nav_default.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0.0f, 10.0f, 0.0f, 10.0f) resizingMode:UIImageResizingModeStretch];
You can try to play with
[[UIBarButtonItem appearance] setBackButtonBackgroundVerticalPositionAdjustment:5 forBarMetrics:UIBarMetricsDefault];
in ios 5 after you put the insets
I'm trying to customize the back button of a UINavigationBar using the iOS 5 UIAppearance API. The image I want to use is this: https://www.dropbox.com/s/ce83rw0e3vs9dwo/bt-back.png and the code is the following:
// Customize back button items differently
UIEdgeInsets aInset = UIEdgeInsetsMake(10, 10, 10, 10);
UIImage *buttonBack30 = [[UIImage imageNamed:#"bt-back.png"] resizableImageWithCapInsets:aInset];
UIImage *buttonBack24 = [[UIImage imageNamed:#"bt-back.png"] resizableImageWithCapInsets:aInset];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:buttonBack30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:buttonBack24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];
Now, the output of that code is the following: http://i.imgur.com/X6QBK.png
I know I have to set the UIEdgeInsets to a proper value, but I've being reading the documentation and it seems that it's only possible to preserve the edges and not the center, witch seems to be the thing I need to do.
Is there any way to preserve the center and not the edges? If not, what's the dimensions I have to generate the PNG so iOS doesn't stretch it?
Thanks a lot
Could you use the method
- (UIImage *)backButtonBackgroundImageForState:(UIControlState)state
barMetrics:(UIBarMetrics)barMetrics
to retrieve the back button's background image, retrieve its size property, and then use this for the size to make your custom image?