Here is my problem. I am customizing a UISegmentedControl by setting the background and divider images in the following way:
[[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];
[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
When I try to make the 1st segmented selected within viewDidLoad
self.segmentedControl.selectedIndex = 1;
I get the following weird thing:
instead of:
Does anyone know if this is a bug and how could I provide a bug report? If not, what could be wrong with my code?
After doing some tests and trying several different locations for the customization, I believe this may indeed be a bug.
Even with a very simple straight UISegmentedControl, this is what I get (using Xcode 4.3.1, iOS 5.1):
After launching and selecting the middle element in code:
After user-clicked away and clicking back on middle element:
I used 3px wide images for the separators and 1px wide images for the backgrounds.
Edit: I think I found a workaround: try queueing the instruction to select the element, rather than executing it in viewDidLoad, like this:
dispatch_async(dispatch_get_main_queue(),^{
self.segmentedControl.selectedSegmentIndex = 1;
});
On my example above, queuing that instruction makes it work just fine.
I think your image CapInsets is incorrect, please double the example in http://www.raywenderlich.com/4344/user-interface-customization-in-ios-5
here is some codes from the Tutorial for quick reference:
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 figured out how to solve the problem after I did a lot of experiments.
Your problem is from the incorrect width setting for the segments.
First point - we need to do UI customization before setting the width of individual segments.
Second point - we need to count the width of the divider(s) and it is very important. When we do customization, the divider(s) is part of the UISegmentedControl elements. The divider is not an overlay. We should count the width of the divider also.
Third point - when we use the set width method for the segments, the segment width does not need to include the divider's width.
If you follow the above rules, you would get a perfect customized UISegmentedControl.
Have you tried to set resizable images?
For example:
UIImage *segmentSelected = [[UIImage imageNamed:@"SegmentSelectedImage"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With