Remove frame of UISegmentedControl - ios

Is there a way in iOS 7 to completely remove the outer frame of an UISegmentedControl? There should be only one rectangle in tint color for the selected segment.

First, create three images and add them your your Image Assets.
Blank (a transparent png of any size)
Highlight (a png of any color and size)
Select (a png of any color and size)
Then add this code:
UIImage *backgroundImage = [UIImage imageNamed:#"Blank"];
UIImage *highlightedImage = [UIImage imageNamed:#"Highlight"];
UIImage *selectedImage = [UIImage imageNamed:#"Select"];
UIImage *dividerImage = [[UIImage alloc] init];
[segmentedControl setBackgroundImage:backgroundImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[segmentedControl setBackgroundImage:highlightedImage forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
[segmentedControl setBackgroundImage:selectedImage forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[segmentedControl setDividerImage:dividerImage forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

Related

UISegmentedControll appearance no border sharp edges

I'm therribly upset. I've spent lot of time and no suitable result.
I want to redesign (AS APPEARANCE) this
to this
Or in programmatic words... from this:
+(void)configureSegmentedControls {
[[UISegmentedControl appearance] setTintColor:[COLOR_PROXY highlightColor]];
[[UISegmentedControl appearance] setBackgroundColor:[COLOR_PROXY darkBackgroundColor]];
[[UISegmentedControl appearance] setDividerImage:[UIImage new] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
NSDictionary *selectedAttributes = #{NSFontAttributeName:[FONT_PROXY fontNormalOfSizeSmall],
NSForegroundColorAttributeName:[UIColor whiteColor]};
[[UISegmentedControl appearance] setTitleTextAttributes:selectedAttributes
forState:UIControlStateSelected];
NSDictionary *normalAttributes = #{NSFontAttributeName:[FONT_PROXY fontNormalOfSizeSmall],
NSForegroundColorAttributeName:[COLOR_PROXY highlightColor]};
[UISegmentedControl appearance] setTitleTextAttributes:normalAttributes
forState:UIControlStateNormal];
NSDictionary *disabledAttributes = #{NSFontAttributeName:[FONT_PROXY fontNormalOfSizeSmall],
NSForegroundColorAttributeName:[COLOR_PROXY lightGrayTextColor]};
[[UISegmentedControl appearance] setTitleTextAttributes:disabledAttributes forState:UIControlStateDisabled];
}
to this:
???
You can achieve this appearance like this:
self.segmentedControl.layer.cornerRadius = 0;
self.segmentedControl.layer.borderColor = [UIColor whiteColor].CGColor;
self.segmentedControl.layer.borderWidth = 1.5;
Replace [UIColor whiteColor] with the background color of the segmented control's superview.
You can set the width of the segments (using setWidth:forSegmentAtIndex:) so you can easily make the left and right end segments larger (say 10px larger) than the others and then you can crop off 10px from either end and have square corners. You don't have to make it larger than the screen width, instead put it inside a UIView and use it to crop the ends.
On the other hand just could just make your own segmented control using a set of custom UIButtons inside a UIControl.
segmentControl.layer.borderColor = [UIColor clearColor].CGColor;
segmentControl.layer.borderWidth = 1.5;
segmentControl.tintColor = [UIColor clearColor];
if background color is white then
segmentControl.layer.borderColor = [UIColor whiteColor].CGColor;
segmentControl.layer.borderWidth = 1.5;
segmentControl.tintColor = [UIColor whiteColor];
using images this may be achieved.
[segmented setImage:nil forSegmentAtIndex:0];
[segmented setImage:nil forSegmentAtIndex:1];
[segmented setTintColor:[UIColor darkGrayColor]];
[segmented setTitle:#"1" forSegmentAtIndex:0];
[segmented setTitle:#"2" forSegmentAtIndex:1];
[segmented setDividerImage:[self imageFromColor2:[UIColor darkGrayColor] withFrame:CGRectMake(0, 0, 1, segmented.frame.size.height)]
forLeftSegmentState:(UIControlStateNormal | UIControlStateSelected | UIControlStateHighlighted)
rightSegmentState:(UIControlStateNormal | UIControlStateSelected | UIControlStateHighlighted)
barMetrics:UIBarMetricsDefault];
[segmented setBackgroundImage:[self imageFromColor2:[UIColor lightGrayColor] withFrame:CGRectMake(0, 0, segmented.bounds.size.width/2.0+1, segmented.frame.size.height)]
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
to create color images:
- (UIImage *)imageFromColor2:(UIColor *)color withFrame:(CGRect)frame{
CGRect rect = frame;
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
and as a result i had this segmented control. you can play with the colors and get what you want.
only solution (for appearance) I've found is using images only...
UIImage *activeImage = [[UIImage imageNamed:#"btn_bg_active"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage *inactiveImage = [[UIImage imageNamed:#"btn_bg_inactive"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[[UISegmentedControl appearance] setBackgroundImage:inactiveImage forState:UIControlStateDisabled barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:inactiveImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:activeImage forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:inactiveImage forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:[UIImage new] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:[UIImage new] forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:[UIImage new] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

UISegmentedControl messed up after customization

So after I customize the UISegmentedControl, everything got messed up, the label got shifted and there is a white vertical line which I don't know where it came from. The divider also got off-center, I have checked that the black line is at 40-41px of a 80px image, so it must be centered. Want am I doing wrong or have anybody experience this before?
Before Customization:
After Customization:
note: the divider images is a horizontal flip of each other.
Code:
UIImage *un_sel = [UIImage imageNamed:#"divider-un-sel"];
UIImage *sel_un = [UIImage imageNamed:#"divider-sel-un"];
[_segmentControl setDividerImage:un_sel forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[_segmentControl setDividerImage:sel_un forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
UIImage *normal = [[UIImage imageNamed:#"segment-normal"] stretchableImageWithLeftCapWidth:20 topCapHeight:0];
UIImage *selected = [[UIImage imageNamed:#"segment-selected"] stretchableImageWithLeftCapWidth:20 topCapHeight:0];
[_segmentControl setBackgroundImage:normal forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[_segmentControl setBackgroundImage:selected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
Solved the problem by using
[[UIImage imageNamed:#"segment-normal"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
instead of stretchableImageWithLeftCapWith:topCapHeight

UISegmentedControl wrong dividerImage

I am custumizing all segmented controls in my app with the following code.Initially I set the selected segment to index 2.
Everything works perfect in IOS 6.While I was testing the app on IOS5, I realised that the initial setting of segmented control had a bug.The separation image between selected and unselected state is not set right.Due to that it looks like this.
If i change the selected segments by tapping the segmentedcontrol behaves normal.It is very weird.What elsse shall i do to prevent this strange behaviour?
UISegmentedControl *localSegmentedControl = [[UISegmentedControl alloc] init];
if ([localSegmentedControl respondsToSelector:#selector(setBackgroundImage:forState:barMetrics:)]) {
UIImage *segmentUnselectedSelectedDivider = [UIImage imageNamed:#"segmentedControlSeperatorNS.png"];
UIImage *segmentSelectedUnselectedDivider = [UIImage imageNamed:#"segmentedControlSeperatorSN.png"];
UIImage *segmentUnselectedUnselectedDivider = [UIImage imageNamed:#"segmentedControlSeperatorNN.png"];
UIImage *segmentUnselected = [[UIImage imageNamed:#"barButtonPlain.png"] stretchableImageWithLeftCapWidth:7 topCapHeight:0];
UIImage *segmentSelected = [[UIImage imageNamed:#"doneButton.png"] stretchableImageWithLeftCapWidth:7 topCapHeight:0];
[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected
forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected
forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentUnselectedUnselectedDivider
forLeftSegmentState:UIControlStateNormal
rightSegmentState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselectedDivider
forLeftSegmentState:UIControlStateSelected
rightSegmentState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentUnselectedSelectedDivider
forLeftSegmentState:UIControlStateNormal
rightSegmentState:UIControlStateSelected
barMetrics:UIBarMetricsDefault];
}
After trying all relevant approached explained in Customizing UISegmentedControl in iOS 5
i figured out that the problem is related with the width of the separation line.The tutorial about segmented control customisation in http://www.raywenderlich.com/4344/user-interface-customization-in-ios-5 assumes that the separation images are wider than 2px (in Retina).
I made them exactly 2px wide and the problem is resolved.
I think it is a known bug.
It is the same here with a workaround, may work for you.
Customizing UISegmentedControl in iOS 5
When i use segment control I was very tired the same problem. I solved that code
UIImage *segmentSelected =
[[UIImage imageNamed:#"ikisiSecildiKirmizi.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 5, 15)];
UIImage *segmentUnselected =
[[UIImage imageNamed:#"ikisiSecilmediGri.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 5, 15)];
UIImage *segmentSelectedUnselected =
[[UIImage imageNamed:#"solSecili.png"]resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 5, 15)];
UIImage *segUnselectedSelected =
[[UIImage imageNamed:#"sagSecili.png"]resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 5, 15)];
UIImage *segmentUnselectedUnselected =
[[UIImage imageNamed:#"ikisideSecilmemis.png"]resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 5, 15)];
[fiyatSaat setBackgroundImage:segmentUnselected
forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[fiyatSaat setBackgroundImage:segmentSelected
forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[fiyatSaat setDividerImage:segmentUnselectedUnselected
forLeftSegmentState:UIControlStateNormal
rightSegmentState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
[fiyatSaat setDividerImage:segmentSelectedUnselected
forLeftSegmentState:UIControlStateSelected
rightSegmentState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
[fiyatSaat setDividerImage:segUnselectedSelected
forLeftSegmentState:UIControlStateNormal
rightSegmentState:UIControlStateSelected
barMetrics:UIBarMetricsDefault];
NSDictionary *attributes = [NSDictionary dictionaryWithObject:[UIColor blackColor]
forKey:UITextAttributeTextColor];
[fiyatSaat setTitleTextAttributes:attributes
forState:UIControlStateNormal];
NSDictionary *attributes2 = [NSDictionary dictionaryWithObject:[UIColor whiteColor]
forKey:UITextAttributeTextColor];
[fiyatSaat setTitleTextAttributes:attributes2
forState:UIControlStateHighlighted];

UISegmentedControl background image strange behavior

I'm working on an iOS project and came across this strange issue. I have a UISegmentedControl element of bar style. It has 3 segments. The segments have fixed sizes of 80. I also have 3 images with each segment selected to set as background. Here is one of them`
When view is loaded, one of the segments is set as selected and this image is set as background like this:
[self.genderSelectionButton setBackgroundImage:[UIImage imageNamed:#"gender-switch01.png"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
Now when I run the project on 5.1 Simulator, I get this distorted view for segmented button:
As you can see, the middle segment keeps the size I gave, but the image is kind of stretched from the middle to the edges.
Also selected segment is highlighted even though I have set it to NO.
In the method that listens to button selection, I change background image and get the following:
(background image is stretched again...)
Almost the same happens on iOS6.
Now am I doing something wrong, or is there a way to fix this??
EDIT
Found a better implementation with separate images for normal button, selected button and dividers. See the answer below.
It appears that setting full background image is not the best way to handle custom segmented button. Example found here.
Here is the basic code that does everything:
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];

I want to change UISegmentedControl images after selection

I have UISegmentedControl object in which I took images array. Now I want to change this images after selection of each object like UIButton control in which we can set image for selection and also for non selection.
Here is my code
NSArray *itemArray;
itemArray = [NSArray arrayWithObjects:
[UIImage imageNamed:#"grey.png"],
[UIImage imageNamed:#"overlay.png"],
[UIImage imageNamed:#"marker.png"],
nil];
segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
[segmentedControl addTarget:self action:#selector(segmentedControlIndexChanged) forControlEvents:UIControlEventValueChanged];
You can customise segment control with your own images for selected state and normal state in iOS 5
Try this:
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];
You can also Check Complete UI customisation at http://www.raywenderlich.com/4344/user-interface-customization-in-ios-5

Resources