【问题标题】:UISegmentedControl boundsUISegmentedControl 边界
【发布时间】:2013-10-08 21:58:13
【问题描述】:

我想为 UISegmentedControl 提供以下方面:

注意灰色背景视图,以及分段控件非选中项的白色背景。

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

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

提前谢谢你,

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

【问题讨论】:

  • 可以设置segmented.backgroundColor=[UIColor clearColor];
  • @Viruss mca:感谢您的评论,但在这种情况下,“Tratadas”背后的背景显示为灰色,而不是白色。
  • 您也可以使用两个 UIButton 代替 UISegmentedControl 作为替代解决方案。

标签: iphone ios7 uisegmentedcontrol


【解决方案1】:

设置_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 的右侧。所以最简单的去除它的方法是制作固定大小的片段并调整它们以获得适当的宽度。

【讨论】:

  • 感谢您的回答。这样做,结果会更好,但远非完美。请参阅我原始帖子中的图片。
  • 再次感谢您。最后,我同意了马蒂亚斯的回答,但你帮了我很多。我已经测试了您的解决方案,它也适用于我。
【解决方案2】:

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

结果:

【讨论】:

  • 如果您使用自动布局,您可以将“背景视图”固定为匹配 SegmentControl 的宽度/高度等,因此无需使用负 1 进行调整。当然您可以使用运行时属性来设置背景视图的cornerRadius也是
【解决方案3】:

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

有一种方法可以计算 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 版本上检查您的应用。我们依赖于实施细节,而且这些细节每天都在变化。幸运的是,如果他们改变了实现,没有什么不好的事情发生。它只是看起来不太好。

【讨论】:

  • 非常感谢!它工作正常。你给了一个很好的解释。
【解决方案4】:

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

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



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

- (UIView *)addBackgroundViewBelowSegmentedControl:(UISegmentedControl *)segmentedControl;

【讨论】:

    猜你喜欢
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-17
    • 2020-05-26
    • 2021-01-04
    • 1970-01-01
    相关资源
    最近更新 更多