Appearance proxy affected by upgrade to iOS 6 - background

My app implements a custom segmented control background image using:
// customise the 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:segmentUnselected forState:UIControlStateDisabled 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];
It was perfectly working before I updated to XCode 4.5 and iOS6. Now it's like that:
as you can see the background images size were altered. Did any anybody have the same problem?
Also some of the background images for some screen look shorter the requested. In one of them for example I have a blank space.

Make sure you name your images with #2x if they're at that resolution.
I had a similar-looking problem which was fixed when I added that.

Related

Adding image to the segment controller

Prior to iOS 7 it was easy to add colored image to the segment controller, but now if I add image to it, only the image is visible with the default Tint color and not the actual color.
Does any one have idea about this, if so kindly help me out.
Thanx in advance.
Fix it with: imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal
UIImage *segmentImage = [UIImage imageNamed:#"Example"];
if ([UIImage instancesRespondToSelector:#selector(imageWithRenderingMode:)]) {
segmentImage = [segmentImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
[self.control insertSegmentWithImage:segmentImage atIndex:i animated:NO];
This may help you
UIImage *segmentSelected = [[UIImage imageNamed:#"Off.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(6, 6, 6, 6)];
UIImage *segmentUnselected = [[UIImage imageNamed:#"On.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(6, 6, 6, 6)];
UIImage *segmentSelectedUnselected =
[UIImage imageNamed:#"dividerOn.png"];
UIImage *segUnselectedSelected =
[UIImage imageNamed:#"dividerOff.png"];
[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected
forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected
forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected
forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segUnselectedSelected
forLeftSegmentState:UIControlStateNormal // | UIControlStateHighlighted
rightSegmentState:UIControlStateSelected
barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segUnselectedSelected
forLeftSegmentState:UIControlStateHighlighted
rightSegmentState:UIControlStateSelected
barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected
forLeftSegmentState:UIControlStateSelected
rightSegmentState:UIControlStateNormal //| UIControlStateHighlighted)
barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected
forLeftSegmentState:UIControlStateSelected
rightSegmentState:UIControlStateHighlighted
barMetrics:UIBarMetricsDefault];
UIFont *font = [UIFont systemFontOfSize:16.0f];
UIColor *textColor = [UIColor darkGrayColor];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
font, #"NSFontAttributeName",
textColor, #"NSForegroundColorAttributeName",
nil];
[[UISegmentedControl appearance] setTitleTextAttributes:attributes
forState:UIControlStateNormal];
simply change the segmentController tintcolor to UIColor clearColor, use style controlstyleborder
SegmentControl.backgroundColor= [UIColor clearColor];
[SegmentControl setTintColor:[UIColor clearColor]];

change background image of navigation bar based on orientation

Is there a way to change the background image of navigation bar based on orientation? I tried using methods in the app delegate such as :
-(void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame
{
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientation == (UIInterfaceOrientationMaskPortrait)||orientation==(UIInterfaceOrientationMaskPortraitUpsideDown)){
UIImage *myImage = [UIImage imageNamed:#"borderP.png"];
UIImage * imageBottom = [UIImage imageNamed:#"bottomP.png"];
[[UIToolbar appearance] setBackgroundImage:imageBottom forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:myImage forBarMetrics:UIBarMetricsDefault];
[[UIToolbar appearance] setBackgroundImage:imageBottom forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
NSLog(#"******P******");
}
else if(orientation == (UIInterfaceOrientationMaskLandscapeLeft||orientation== UIInterfaceOrientationMaskLandscapeRight)){
UIImage *myImage = [UIImage imageNamed:#"borderL.png"];
UIImage * imageBottom = [UIImage imageNamed:#"borderL.png"];
[[UIToolbar appearance] setBackgroundImage:imageBottom forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:myImage forBarMetrics:UIBarMetricsDefault];
[[UIToolbar appearance] setBackgroundImage:imageBottom forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
NSLog(#"******L********");
}
}
but the back ground image does not change.
Any advice?
The appearance proxy only applies only to new instances. To modify an instance that already exists, you you need to call setBackgroundImage:forToolbarPosition:barMetrics: on it directly.

UIAppearence Support for IOS 6 - unexpected results

Below code is perfectly working fine iOS 5, but not on iOS 6 or above.
What I want that for Email composer sheet the navigationBar image will be different then other UINavigationBar classes. I can't understand that debug pointer is responding the appearance method but on device it shows navigationBar image as "bgNavigationBar.png"; expected is "bgNavigationBar_2.png".
Please guide me.......
if ([[UINavigationBar class]respondsToSelector:#selector(appearance)]) {
UIImage *logoImage44 = [[UIImage imageNamed:#"bgNavigationBar.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UINavigationBar appearance] setBackgroundImage:logoImage44 forBarMetrics:UIBarMetricsDefault];
UIImage *ImagePlain = [[UIImage imageNamed:#"bgNavigationBar_2.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UINavigationBar appearanceWhenContainedIn:[MFMailComposeViewController class], nil] setBackgroundImage:ImagePlain forBarMetrics:UIBarMetricsDefault];
}
This thing is not working in ios6.
[[UINavigationBar appearanceWhenContainedIn:[MFMessageComposeViewController class], nil] setBackgroundImage:[UIImage imageNamed:#"bgNavigationBar_2.png"] forBarMetrics:UIBarMetricsDefault];
Just you need to set this property in your Mail Handler Class.
if (![[UINavigationBar class]respondsToSelector:#selector(appearance)])
{
UIView *backgroundView = [[[UIView alloc] initWithFrame:CGRectMake(0,0,320,44)]autorelease];
[backgroundView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"bgNavigationBar_2.png"]]];
controller.topViewController.navigationItem.titleView = backgroundView ;
}
else
{
UIImage *gradientImagePlain = [[UIImage imageNamed:#"bgNavigationBar_2.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UINavigationBar appearance] setBackgroundImage:gradientImagePlain forBarMetrics:UIBarMetricsDefault];
}
and then reset another image for all other navigation controller's background image.
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
[self.parentController dismissModalViewControllerAnimated:YES];
UIImage *gradientImagePlain = [[UIImage imageNamed:#"bgNavigationBar.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UINavigationBar appearance] setBackgroundImage:gradientImagePlain forBarMetrics:UIBarMetricsDefault];
}
Hope this will work for you.

How can I correctly change the way a UITabBar appears using the appearance proxy?

Since I am developing an iOS >= 5.0 application, I am trying to change the appearance of the main UI components through the appearance proxies.
When dealing with the UITabBar component, I correctly changed its tintColor to a light shade of gray trough the [[UITabBar appearance] setTintColor:] method. But doing this, the UITabBarItems included in the bar are quite impossible to see, since they retain the old gray/white color in their title label.
I tried to change their appearance through the [UITabBarItem appearance] proxy, but there is no way to make them visible.
Can anyone suggest me a way to solve this problem? Thank you!
Hi this will work for what you want to do
// Customize the UIBarButtonItem
UIImage *button30 = [[UIImage imageNamed:#"button_textured_30"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
UIImage *button24 = [[UIImage imageNamed:#"button_textured_24"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
[[UITabBarItem appearance] setBackgroundImage:button30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UITabBarItem appearance] setBackgroundImage:button24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];
[[UITabBarItem appearance] setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor colorWithRed:82.0/255.0
green:82.0/255.0
blue:82.0/255.0
alpha:1.0], UITextAttributeTextColor,
[UIColor colorWithRed:242.0
green:237.0
blue:237.0
alpha:1.0], UITextAttributeTextShadowColor,
[NSValue valueWithUIOffset:UIOffsetMake(0,1)], UITextAttributeTextShadowOffset,
[UIFont fontWithName:#"Helvetica" size:0.0], UITextAttributeFont,nil]
forState:UIControlStateNormal];
Happy Coding :)

UISegmentedControl segment width of is not set when the background image is set

I have a segmented control and I want first and last items to be of specified width (say, wider than others). When I setWidth:forSegmentAtIndex: for standard-styled segmentedControl (i.e. [[UISegmantedControl appearence] setBackgroundImage:forState:barMetrics:] not set), things behave themselves as they should. But when I set background image, segments width doesn't change.
Here is my code:
[[UISegmentedControl appearance] setBackgroundImage:[[UIImage imageNamed:#"btn_normal.png"] stretchableImageWithLeftCapWidth:25 topCapHeight:0] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:[[UIImage imageNamed:#"btn_selected.png"] stretchableImageWithLeftCapWidth:25 topCapHeight:0] forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:[UIImage imageNamed:#"nn.png"] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:[UIImage imageNamed:#"sn.png"] forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:[UIImage imageNamed:#"ns.png"] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[self.segmentedControl setContentMode:UIViewContentModeScaleToFill];
[self.segmentedControl setWidth:100.0 forSegmentAtIndex:0];
[self.segmentedControl setWidth:100.0 forSegmentAtIndex:4];
With this, all my segments appear automatically sized to the equal width.
And when I comment out all above this
[self.segmentedControl setContentMode:UIViewContentModeScaleToFill];
[self.segmentedControl setWidth:100.0 forSegmentAtIndex:0];
[self.segmentedControl setWidth:100.0 forSegmentAtIndex:4];
the sizes are set correctly.
Here is my question: how can I set sizes for the segments with background images?
I'm new to cocoa-touch and objective-c, so I might be missing something...
Could you help please?
I think when you use [UISegmentedControl appearance] proxy it overrides "setWidth:forSegmentAtIndex:" method values. So possible solutions:
1)
[[UISegmentedControl appearance] setContentMode:UIViewContentModeScaleToFill];
[[UISegmentedControl appearance] setWidth:100.0 forSegmentAtIndex:0];
[[UISegmentedControl appearance] setWidth:100.0 forSegmentAtIndex:4];
I would not recommend to use this because it will set custom width for 0 and 4 segments for every segmented control in your app.
2)
[self.segmentedControl setBackgroundImage:[[UIImage imageNamed:#"btn_normal.png"] stretchableImageWithLeftCapWidth:25 topCapHeight:0] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[self.segmentedControl setBackgroundImage:[[UIImage imageNamed:#"btn_selected.png"] stretchableImageWithLeftCapWidth:25 topCapHeight:0] forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[self.segmentedControl setDividerImage:[UIImage imageNamed:#"nn.png"] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[self.segmentedControl setDividerImage:[UIImage imageNamed:#"sn.png"] forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[self.segmentedControl setDividerImage:[UIImage imageNamed:#"ns.png"] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
If you need that all segmented controls in your app should have custom background then I would recommend to write your own proxy method. Something like this:
- (UISegmentedControl *) customSegmentedControl {
UISegmentedControl *segmentedControl = [ [ [UISegmentedControl alloc] init] autorelease];
[segmentedControl setBackgroundImage: [ [UIImage imageNamed: #"btn_normal.png"] stretchableImageWithLeftCapWidth: 25 topCapHeight: 0] forState: UIControlStateNormal barMetrics: UIBarMetricsDefault];
[segmentedControl setBackgroundImage: [ [UIImage imageNamed: #"btn_selected.png"] stretchableImageWithLeftCapWidth: 25 topCapHeight: 0] forState: UIControlStateSelected barMetrics: UIBarMetricsDefault];
[segmentedControl setDividerImage: [UIImage imageNamed: #"nn.png"] forLeftSegmentState: UIControlStateNormal rightSegmentState: UIControlStateNormal barMetrics: UIBarMetricsDefault];
[segmentedControl setDividerImage: [UIImage imageNamed: #"sn.png"] forLeftSegmentState: UIControlStateSelected rightSegmentState: UIControlStateNormal barMetrics: UIBarMetricsDefault];
[segmentedControl setDividerImage: [UIImage imageNamed: #"ns.png"] forLeftSegmentState: UIControlStateNormal rightSegmentState: UIControlStateSelected barMetrics: UIBarMetricsDefault];
return segmentedControl;
}
I solved this by writing custom control, based on this http://idevrecipes.com/2010/12/11/custom-segmented-controls/