自从iOS7,UIView有了一个新的属性tintColor,它是用来在视觉上说明屏幕上哪些控件是活跃的或者有相关的活动。例如bar button items和tab bar items默认使用tintColor。如果一个view没有显示地指定tintColor,它将继承父视图的tintColor,因此在整个视图层次结构中将有一个连锁反应。最简单的情况是你可以通过一行代码来给整个APP指定一个颜色主题:
[[UIApplication sharedApplication] keyWindow].tintColor = [UIColor orangeColor];因为UIWindow继承自UIView,所以我们可以指定一个tintColor,然后应用内的所有子视图将继承这个颜色。为了证明tintColor对各种用户界面元素的影响,接下来将举一个tabbar应用的例子,第一个页面有6个按钮,每个按钮会改变UIWindow的tintColor为一个颜色。第二个页面将展示tintColor对不用界面元素的影响。左上角的 red按钮会设置UIView的tintColor,右上角的blue按钮会设置UIButton自身和tabbar的tintColor。最后UISegmentedControl将控制整个苹果图标的外观。当我们按下第一页的按钮的时候,UIButton的文本就会自动适应按钮指定的颜色。相似的,tabbar
上的图标和文本也会适应新的颜色。
相似地,我们可以设置指定视图的tintColor,假设一个有tabbar应用设置的UIWindow的tintColor为蓝色,为了区分出tab和主界面,我们可以设定主界面的tintColor为红色。iOS7之前实现要用很多行颜色设定的代码,但是现在只需要简单的一行代码改变主视图的tintColor来设定主视图自身和它所有子视图的颜色。
self.view.tintColor = [UIColor redColor];
设置按钮的tintColor会改变按钮上文本的颜色,但是不会改变按钮兄弟视图和父视图的颜色。
myButton.tintColor = [UIColor blueColor];
iOS7还能够在alert或者action sheet出现的时候去色或者“暗”着色。这向用户表明这些控件当前不可用。按下第二个页面的步进控件就会看到这个效果,如下图:
iOS7中UIImage添加了一个新的属性renderingMode,可以和tintColor结合着使用,renderingMode有三个选项,第一个是UIImageRenderingModeAutomatic,正如字面的意思自动根据UIImage的使用场景和tintColor来填充颜色,例如UIImageView不会根据tintColor渲染UIImage,而UIBarButtonItem会根据tintColor自动填充UIImage。第二个选项是UIImageRenderingModeAlwaysOriginal,UIImage总是会根据自身的颜色渲染图像。第三个是UIImageRenderingModeAlwaysTemplate,这个模式将会用tintColor渲染所有UIImage不透明的地方,也就是说设置为这个属性的UIImage被当做了一个模板,如果你希望图像的哪些部分不用tintColor渲染的话,你需要把哪些部分设置成完全透明的。在例子中的第二个界面中的Segmented控件展示了这个功能。
正如我们看到的,tintColor和renderingMode两个属性给了我们很用的功能,但是使用tintColor有几件事情我们需要注意,第一是tintColor不支持UIAppearance。这是非常不幸的,因为如果支持的话,我们可能通过几行代码就会改变整个APP的颜色,例如我们想要每一个UIButton以一个特殊颜色凸现出来,我们不得不单独的设置每一个按钮的tintColor。第二当获取一个UIView的tintColor的时候,总是返回一个有效的颜色。这是因为如果视图的tintColor是nil就会返回父视图的tintColor。如果所有的视图包括UIWindow的tintColor都是nil的话,UIWindow总会返回一个默认的值,这个值是RGB(0,122,255).第三如果你自定义了一个视图并且用到了tintColor,你应该实现tintColorDidChange方法以便于我们可以在必要的时候更新视图的渲染。
- (void)tintColorDidChange
这个方法的默认实现是执行标准的更新。例如你子类化了一个UIImageView并且image的renderingImage设置为UIImageRenderingModeAlwaysTemplate或者子类了UIButton,当tintColor更新的时候自动重绘。覆盖这个方法的目的是为了当tintColor改变的时候自定义一些行为。例如我们可以子类一个UIView来根据用户的选择改变颜色主题。例子中的颜色主题是橘色和黑色两个选项,当用户选择一个选项的时候,我们可以自定义UIView和设置tintColor为橙色,接下来可以设置子视图的tintColor为黑色。在iOS6中也有tintColor属性但是这个属性是用于navigation bars、tab bars、toolbars、search bars和scope bar的北京颜色。在iOS7中我们要设置这些控件的背景颜色我们应该使用barTintColor。
tintColor十分有用并且非常容易使用,通过这个属性用户就可以通过观看视图来判断当前哪些控件是活跃的并且有相关的活动。