在IOS6下制作IOS7风格的UISegmentedControl

通过UISegmentedControl的setBackgroundImage:forState:barMetrics:方法和setDividerImage:forLeftSegmentState:rightSegmentState:barMetrics:方法,以及一点点Photoshop的基本功,就能在IOS6下做出IOS7风格的UISegmentedControl

起因

现在IOS平台下的应用开发都已经趋向IOS7的风格,哪怕系统本身不是IOS7的。就比如我们这个应用,开始的时候使用按钮来实现类似UISegmentedControl的UI和功能,但是后期,需求一改,要求用原生的实现。整个应用都是IOS7风格的,在IOS7下,使用原生的倒也简单,但是在IOS6下面就困难了,立体化的控件是那样的突兀。

没办法,只好在一起走上Google之路,不过总算有个好结果。

设置UISegmentedControl的背景

在看下文之前,先看这里,没有这个在stackoverflow上面的精彩回答,也就不会有这篇文章了,万分感谢!

有了上面的基本技术知识储备,再上一张最终效果图,方便描述思路
最终效果图

从stackoverflow的那个回答,可以知道,自定义一个UISegmentedControl需要的素材有三种类型:选中时的按钮图片、没选中时候的按钮图片和两个按钮中间的图片(这里说的是只有左右两个按钮的情况)

在那个回答中,作者很耐心的给出了针对性的5张图片,但是在我的最终效果里面,中间的那个线是一直不变的,不管两边如何变化,所以我只需要三张图片
需要的素材

再然后就是复制修改代码了:

/* Unselected background */
UIImage *unselectedBackgroundImage = [[UIImage 
                           imageNamed:@"segment-unselected-item.png"] 
          resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
[[UISegmentedControl appearance] setBackgroundImage:unselectedBackgroundImage
                                           forState:UIControlStateNormal
                                         barMetrics:UIBarMetricsDefault];

/* Selected background */
UIImage *selectedBackgroundImage = [[UIImage 
                           imageNamed:@"segment-selected-item.png"] 
          resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
[[UISegmentedControl appearance] setBackgroundImage:selectedBackgroundImage
                                           forState:UIControlStateSelected
                                         barMetrics:UIBarMetricsDefault];

/* Image between two unselected segments */
UIImage *bothUnselectedImage = [[UIImage 
                           imageNamed:@"segment-middle.png"] 
          resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)];
[[UISegmentedControl appearance] setDividerImage:bothUnselectedImage
                             forLeftSegmentState:UIControlStateNormal
                               rightSegmentState:UIControlStateNormal
                                      barMetrics:UIBarMetricsDefault];

/* Image between segment selected on the left and unselected on the right */
UIImage *leftSelectedImage = [[UIImage 
                           imageNamed:@"segment-middle.png"] 
          resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)];
[[UISegmentedControl appearance] setDividerImage:leftSelectedImage
                             forLeftSegmentState:UIControlStateSelected
                               rightSegmentState:UIControlStateNormal
                                      barMetrics:UIBarMetricsDefault];

/* Image between segment selected on the right and unselected on the left */
UIImage *rightSelectedImage = [[UIImage 
                                     imageNamed:@"segment-middle.png"] 
                    resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)];
[[UISegmentedControl appearance] setDividerImage:rightSelectedImage
                             forLeftSegmentState:UIControlStateNormal
                               rightSegmentState:UIControlStateSelected
                                      barMetrics:UIBarMetricsDefault];

在完成上述代码之后,运行,就能看到UISegmentedControl的背景已经成功的IOS7风格化了
完成UISegmentedControl的背景

但还是有些瑕疵,在选中的segment上,字体是白色的,很难识别,而且字体对中文的支持不友好,一大一小的,所以还需要一些美化工作

一些美化

万能的stackoverflow,再次从它那边找到了完美方案。对于中文,使用Helvetica字体是一个不错的选择,然后可以选择性的去掉不好看的阴影,别的设定就是看个人需要,随意增删了。下面给出我的设定:

NSDictionary *selectedAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                [UIFont fontWithName:@"Helvetica" size:14.0f], UITextAttributeFont,
                                [UIColor colorWithRed:11/255.0 green:96/255.0 blue:175/255.0 alpha:1],
                                UITextAttributeTextColor,
                                [UIColor clearColor], UITextAttributeTextShadowColor,
    nil];
[segment setTitleTextAttributes:selectedAttributes forState:UIControlStateSelected];

NSDictionary *normalAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                       [UIFont fontWithName:@"Helvetica" size:14.0f], UITextAttributeFont,
                                       [UIColor whiteColor], UITextAttributeTextColor,
                                       [UIColor clearColor], UITextAttributeTextShadowColor,
                                       nil];
[segment setTitleTextAttributes:normalAttributes forState:UIControlStateNormal];

好了,一个IOS7风格的UISegmentedControl完成了,下面看看实现的和真正原生的IOS7风格的UISegmentedControl有什么区别不

区别

边框的细线有点偏粗,字体偏大,圆角过小。这些还是明天再改吧,困了…

后续新增

  • 修改了segment-unselected-item.png的细线宽度,由2px改成1px(@2x的由4px改成2px)
  • 字体尺寸修改为12.0f
  • 修改segment-unselected-item@2x.png和segment-selected-item@2x.png这两张图片的圆角,由5px增加为10px(根据IOS7的风格,UISegmentedControl的圆角弧度是10px)

在上一张最终的结果比较

最终比较

作者: happyWang

Hello, the beautiful world

发表评论