自定义 UISegmentedControl 样式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义 UISegmentedControl 样式相关的知识,希望对你有一定的参考价值。

参考技术A 系统的 UISegmentedControl 是个挺方便的控件,这里来讲讲在 Swift3 下自定义 UISegmentedControl 的样式,包括修改底色,边框颜色等等。

要了解 UISegmentedControl 各个部分的组成,可以在官方的文档中找到 UISegmentedControl 文档 。着重注意这个图:

上面这幅图明确的列出了 UISegmentedControl 各个部分所控制的方法。下面就开始自定义吧。

首先我们先做一个通过颜色生成图片的的一个扩展方法:

接着,我们可以为 UISegmentedControl 建立一个可以自定义颜色的扩展方法:

这个扩展方法我只暴露了三种颜色的修改,大家可以根据自己需求修改。
最后就是使用了,注意这里如果进行了自定义,不能用 autoLayout 了, 需指定 Segement 的位置大小,不然显示出来的效果被压缩成了一条线,我估计是 setBackgroundImage 的方法需要把 1x1 的颜色图片进行填充,如果不指定大小会出差错。

个人比较喜欢用 extension 扩展方法,这里大家直接拷贝就能够使用了,祝大家自定义愉快吧~

UISegmentedControl 错误自定义处理

【中文标题】UISegmentedControl 错误自定义处理【英文标题】:UISegmentedControl wrong customization handling 【发布时间】:2012-08-04 10:55:01 【问题描述】:

我使用以下代码自定义了 UISegmentedControl 的外观:

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];

如下图所示,一切看起来都很好,切换时其他部分看起来也不错:

但是当我从第三段切换到第一段时,段分隔符是错误的(右端没有圆角,所以不是正确的分隔符)。

如果分段控件有更多的段,这种情况总是(且仅)在从第三段切换到第一段时发生。

我发现在 valueChanged: 事件之后向 UISegmentedControl 对象发送 setNeedsLayout 消息可以更正显示。

现在,我自定义分段控件的方式是否有问题,是已知错误还是我应该将其报告为错误?

【问题讨论】:

【参考方案1】:

有点丑陋的解决方法,但我设法用以下方法修复它,直到苹果自己修复它。

首先你需要继承 UISegmentedControl 并添加以下内容:

@implementation MJSegmentedControl

- (void)layoutSubviews

    [super layoutSubviews];
    NSInteger cachedIndex = self.selectedSegmentIndex;
    self.selectedSegmentIndex = 0;
    self.selectedSegmentIndex = cachedIndex;


@end

【讨论】:

以上是关于自定义 UISegmentedControl 样式的主要内容,如果未能解决你的问题,请参考以下文章

UISegmentedControl 错误自定义处理

UINavigationController 的自定义 UIBarButtonItem/UISegmentedControl

如何在 iPad 的导航栏中调整自定义 UISegmentedControl 的大小?

为 UISegmentedControl 定义点击事件

tvos UISegmentedControl 焦点样式不变

UISegmentedControl - 在界面生成器中改变高度