18

我想为 UISegmentedControl 提供以下方面:

在此处输入图像描述

注意灰色背景视图和分段控件非选定项的白色背景。

但是,如果我给我的 UISegmentedControl 一个白色背景,我会得到以下信息:

在此处输入图像描述

请注意 UISegmentedControl 周围的白色方角。我应该怎么做才能避免那个方角?

先感谢您,

编辑:如果我更改 UISegmentedControl 图层的角半径,如 onegray 所建议的,结果会更好,但并不完美(注意右侧的白线):

在此处输入图像描述

4

4 回答 4

16

设置_segmentedControl.layer.cornerRadius = 5;可能会有所帮助。

更新:更复杂的剪辑矩形摆脱 1px 右空间:

    CAShapeLayer* mask = [[CAShapeLayer alloc] init];
    mask.frame = CGRectMake(0, 0, _segmentedControl.bounds.size.width-1, _segmentedControl.bounds.size.height);
    mask.path = [[UIBezierPath bezierPathWithRoundedRect:mask.frame cornerRadius:4] CGPath];
    _segmentedControl.layer.mask = mask;

更新:Matthias Bauch 很好地解释了为什么这个空格出现在UISegmentedControl. 因此,删除它的最简单方法是制作固定大小的片段并调整它们以获得适当的宽度。

于 2013-10-02T13:55:42.113 回答
10

如果这适用于所有 UISegmentedControls,那就有点麻烦了。问题在于 iOS7 中的 1 分。两个段之间的边界不计入段的大小。例如,如果您的 UISegmentedControl 的框架是 320 pt。宽,您必须删除 1 pt。然后除以 2。和 (320-1)/2 是 159.5。iOS 将此值降至 159 pt。你最终得到 1 分。边框和两个 159 pt。段。这是 319,而不是 320。因此是 1pt。SegmentedControl 右侧的行。

有一种方法可以计算分段控件的“实际”(屏幕上呈现的大小)大小。使用该宽度,您可以在 UISegmentedControl 下方添加一个带有圆角的 UIView。此代码应适用于所有配置,即使您在 segmentedControl 中手动调整了段的大小:

- (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 pt。宽的。

由于 UISegmentedControl 使用第一个控件的公式,实际大小为 278 pt。第二个的实际大小是 279 pt。

在此处输入图像描述


问题是这在某种程度上依赖于 UISegmentedControl 的实现。例如,Apple 可以更改实现,以便显示以 0.5 磅结尾的段宽度。他们可以在视网膜显示器上轻松做到这一点。

如果您使用此代码,您应该尽早在新的 iOS 版本上检查您的应用程序。我们依赖于实施细节,而且这些细节每天都在变化。幸运的是,如果他们改变了实现,没有什么不好的事情发生。它只是看起来不太好。

于 2013-10-02T18:18:33.480 回答
2

我知道这是一种 hack,但您可以使用带有白色背景的圆形 UIView 放置在分段控件下方 - 并与分段控件对齐,除了宽度应该等于原始控件的宽度减去 1。

结果: 白色背景的分段控制

于 2013-10-02T15:16:02.950 回答
0

只是为了澄清 Mattias Bauch 的出色回答yourMainView您需要将返回的视图设置为您拥有分段控制的视图(我们称之为)的子视图:

UIView *segmControlBackground = [self addBackgroundViewBelowSegmentedControl:yourSegmentedControl];
[yourMainView addSubview:segmControlBackground];



当然,您需要在头文件 (.h) 中声明新方法:

- (UIView *)addBackgroundViewBelowSegmentedControl:(UISegmentedControl *)segmentedControl;
于 2013-10-04T09:42:06.003 回答