UISegmentedControl wrong customization handling

2019-06-05 20:50发布

问题:

I customized the appearance of a UISegmentedControl using the following code:

UIImage *bg = [UIImage imageNamed:@"segment_bg"];
UIImage *bg_sel = [UIImage imageNamed:@"segment_sel"];
UIImage *leftSep = [UIImage imageNamed:@"segment_div_sx"];
UIImage *rightSep = [UIImage imageNamed:@"segment_div_dx"];

UIEdgeInsets selectionInsets = UIEdgeInsetsMake(0, 8, 0, 8);

[self.segmentedControl setBackgroundImage:[bg resizableImageWithCapInsets:UIEdgeInsetsZero]
                        forState:UIControlStateNormal
                      barMetrics:UIBarMetricsDefault];

[self.segmentedControl setBackgroundImage:[bg_sel resizableImageWithCapInsets:selectionInsets]
                        forState:UIControlStateSelected
                      barMetrics:UIBarMetricsDefault];

[self.segmentedControl setBackgroundImage:[bg resizableImageWithCapInsets:UIEdgeInsetsZero]
                        forState:UIControlStateNormal
                      barMetrics:UIBarMetricsDefault];

[self.segmentedControl setDividerImage:[bg resizableImageWithCapInsets:UIEdgeInsetsZero]
          forLeftSegmentState:UIControlStateNormal
            rightSegmentState:UIControlStateNormal
                   barMetrics:UIBarMetricsDefault];

[self.segmentedControl setDividerImage:rightSep
          forLeftSegmentState:UIControlStateSelected
            rightSegmentState:UIControlStateNormal
                   barMetrics:UIBarMetricsDefault];

[self.segmentedControl setDividerImage:leftSep
          forLeftSegmentState:UIControlStateNormal
            rightSegmentState:UIControlStateSelected
                   barMetrics:UIBarMetricsDefault];

Everything looks fine as you can see in the following image, also other segments look good when switching:

but when I switch from the third segment to the first, the segment divider is wrong (no rounded corners on the right end, so not the correct divider).

If the segmented control has more segments, this happens always (and only) when switching from the third segment to the first.

I found out that sending the setNeedsLayout message to the UISegmentedControl object after the valueChanged: event corrects the display.

Now, is it something wrong with the way I customized the segmented control, is it a known bug or should I report this as one?

回答1:

A bit of an ugly workaround but i managed to fix it with the following until apple fixes it itself.

First you need to subclass UISegmentedControl and add the following:

@implementation MJSegmentedControl

- (void)layoutSubviews
{
    [super layoutSubviews];
    NSInteger cachedIndex = self.selectedSegmentIndex;
    self.selectedSegmentIndex = 0;
    self.selectedSegmentIndex = cachedIndex;
}

@end