Reputation: 487
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?
Upvotes: 27
Views: 21503
Reputation: 1259
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];
Upvotes: 4
Reputation: 297
I had the same problem and solved it by different way. I just commented this line of code:
self.pageController.segmentedControlStyle = UISegmentedControlStyleBar;
And segment bar changed it view to normal state.
Upvotes: 0
Reputation: 1746
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.
Upvotes: 10
Reputation: 973
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];
Upvotes: 1
Reputation: 7227
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.
Upvotes: 1
Reputation: 5787
You may want to try initializing your appearance settings earlier than viewDidLoad
. In the demonstrations I've seen this was usually done in application:didFinishLaunchingWithOptions:
, though any point prior to loading the nib containing the customized views should work.
Upvotes: 0