Ответ 1
Если это должно работать для всех UISegmentedControls, это немного хлопот. Проблема заключается в iOS7 1 pt. граница между двумя сегментами не учитывает размер сегмента. Например. если рамка вашего UISegmentedControl - 320 pt. вам нужно удалить 1 pt. и чем разделить на 2. И (320-1)/2 составляет 159,5. iOS составляет это значение до 159 пт. И вы получите 1 pt. границы и два 159 пт. сегменты. Это 319, а не 320. Следовательно, 1pt. линии справа от вашего сегментаемого управления.
Существует способ вычисления размера "фактического" (размер рендеринга на экране) сегмента. С этой шириной вы можете добавить UIView с закругленными углами ниже UISegmentedControl. Этот код должен работать для всех конфигураций, даже если у вас есть сегменты с ручным размером в сегменте управления:
- (UIView *)addBackgroundViewBelowSegmentedControl:(UISegmentedControl *)segmentedControl {
CGFloat autosizedWidth = CGRectGetWidth(segmentedControl.bounds);
autosizedWidth -= (segmentedControl.numberOfSegments - 1); // ignore the 1pt. borders between segments
NSInteger numberOfAutosizedSegmentes = 0;
NSMutableArray *segmentWidths = [NSMutableArray arrayWithCapacity:segmentedControl.numberOfSegments];
for (NSInteger i = 0; i < segmentedControl.numberOfSegments; i++) {
CGFloat width = [segmentedControl widthForSegmentAtIndex:i];
if (width == 0.0f) {
// auto sized
numberOfAutosizedSegmentes++;
[segmentWidths addObject:[NSNull null]];
}
else {
// manually sized
autosizedWidth -= width;
[segmentWidths addObject:@(width)];
}
}
CGFloat autoWidth = floorf(autosizedWidth/(float)numberOfAutosizedSegmentes);
CGFloat realWidth = (segmentedControl.numberOfSegments-1); // add all the 1pt. borders between the segments
for (NSInteger i = 0; i < [segmentWidths count]; i++) {
id width = segmentWidths[i];
if (width == [NSNull null]) {
realWidth += autoWidth;
}
else {
realWidth += [width floatValue];
}
}
CGRect whiteViewFrame = segmentedControl.frame;
whiteViewFrame.size.width = realWidth;
UIView *whiteView = [[UIView alloc] initWithFrame:whiteViewFrame];
whiteView.backgroundColor = [UIColor whiteColor];
whiteView.layer.cornerRadius = 5.0f;
[self.view insertSubview:whiteView belowSubview:segmentedControl];
return whiteView;
}
Пожалуйста, позаботьтесь о каркасных изменениях самостоятельно.
Смотрите этот снимок экрана, чтобы увидеть разницу между двумя элементами управления. Все фреймы составляют 280 пт. широкий.
Из-за формулы UISegmentedControl использует первый элемент управления, фактический размер которого равен 278 пт. И реальный размер второго - 279 пт.
Проблема в том, что это как-то зависит от реализации UISegmentedControl. Apple может, например, изменить реализацию, так что будет отображаться сегментная ширина, которая заканчивается на 0,5 балла. Они могли легко сделать это на сетчатых дисплеях.
Если вы используете этот код, вы должны проверить свое приложение на новых версиях iOS как можно раньше. Мы полагаемся на детали реализации, и они могут меняться каждый день. К счастью, ничего плохого не происходит, если они меняют реализацию. Это будет выглядеть не очень хорошо.