在iOS 7后,UIView新增加了一个tintColor属性,这个属性定义了一个非默认的着色颜色值,其值的设置会影响到以视图为根视图的整个视图层次结构。它主要是应用到诸如app图标、导航栏、按钮等一些控件上,以获取一些有意思的视觉效果。

tintColor属性的声明如下:

var tintColor: UIColor!

默认情况下,一个视图的tintColor是为nil的,这意味着视图将使用父视图的tint color值。当我们指定了一个视图的tintColor后,这个色值会自动传播到视图层次结构(以当前视图为根视图)中所有的子视图上。如果系统在视图层次结构中没有找到一个非默认的tintColor值,则会使用系统定义的颜色值(蓝色,RGB值为[0,0.478431,1],我们可以在IB中看到这个颜色)。因此,这个值总是会返回一个颜色值,即我们没有指定它。

与tintColor属性相关的还有个tintAdjustmentMode属性,它是一个枚举值,定义了tint color的调整模式。其声明如下:

var tintAdjustmentMode: UIViewTintAdjustmentMode

枚举UIViewTintAdjustmentMode的定义如下:

enum UIViewTintAdjustmentMode : Int {
case Automatic // 视图的着色调整模式与父视图一致
case Normal // 视图的tintColor属性返回完全未修改的视图着色颜色
case Dimmed // 视图的tintColor属性返回一个去饱和度的、变暗的视图着色颜色
}
 

因此,当tintAdjustmentMode属性设置为Dimmed时,tintColor的颜色值会自动变暗。而如果我们在视图层次结构中没有找到默认值,则该值默认是Normal。

与tintColor相关的还有一个tintColorDidChange方法,其声明如下:

func tintColorDidChange()

这个方法会在视图的tintColor或tintAdjustmentMode属性改变时自动调用。另外,如果当前视图的父视图的tintColor或tintAdjustmentMode属性改变时,也会调用这个方法。我们可以在这个方法中根据需要去刷新我们的视图。

示例

接下来我们通过示例来看看tintColor的强大功能(示例盗用了Sam Davies写的一个例子,具体可以查看iOS7 Day-by-Day :: Day 6 :: Tint Color,我就负责搬砖,用swift实现了一下,代码可以在这里下载)。

先来看看最终效果吧(以下都是盗图,请见谅,太懒了):

这个界面包含的元素主要有UIButton, UISlider, UIProgressView, UIStepper, UIImageView, ToolBar和一个自定义的子视图CustomView。接下来我们便来看看修改视图的tintColor会对这些控件产生什么样的影响。

在ViewController的viewDidLoad方法中,我们做了如下设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
override func viewDidLoad() {
    super.viewDidLoad()
 
    println("\(self.view.tintAdjustmentMode.rawValue)")         // 输出:1
    println("\(self.view.tintColor)")                           // 输出:UIDeviceRGBColorSpace 0 0.478431 1 1
 
    self.view.tintAdjustmentMode = .Normal
    self.dimTintSwitch?.on = false
 
    // 加载图片
    var shinobiHead = UIImage(named: "shinobihead")
    // 设置渲染模式
    shinobiHead = shinobiHead?.imageWithRenderingMode(.AlwaysTemplate)
 
    self.tintedImageView?.image = shinobiHead
    self.tintedImageView?.contentMode = .ScaleAspectFit
}

首先,我们尝试打印默认的tintColor和tintAdjustmentMode,分别输出了[UIDeviceRGBColorSpace 0 0.478431 1 1]和1,这是在我们没有对整个视图层次结构设置任何tint color相关的值的情况下的输出。可以看到,虽然我们没有设置tintColor,但它仍然返回了系统的默认值;而tintAdjustmentMode则默认返回Normal的原始值。

接下来,我们显式设置tintAdjustmentMode的值为Normal,同时设置UIImageView的图片及渲染模式。

当我们点击”Change Color”按钮时,会执行以下的事件处理方法:

@IBAction func changeColorHandler(sender: AnyObject) {

    let hue = CGFloat(arc4random() % ) / 256.0
let saturation = CGFloat(arc4random() % ) / 256.0 + 0.5
let brightness = CGFloat(arc4random() % ) / 256.0 + 0.5 let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
self.view.tintColor = color
updateViewConstraints()
} private func updateProgressViewTint() {
self.progressView?.progressTintColor = self.view.tintColor
}

这段代码主要是随机生成一个颜色值,并赋值给self.view的tintColor属性,同时去更新进度条的tintColor值。

注:有些控件的特定组成部件的tint color由特定的属性控制,例如进度就有2个tint color:一个用于进度条本身,另一个用于背景。

点击”Change Color”按钮,可得到以下效果:

可以看到,我们在示例中并有没手动去设置UIButton, UISlider, UIStepper, UIImageView, ToolBar等子视图的颜色值,但随着self.view的tintColor属性颜色值的变化,这些控件的外观也同时跟着改变。也就是说self.view的tintColor属性颜色值的变化,影响到了以self.view为根视图的整个视图层次结果中所有子视图的外观。

看来tintColor还是很强大的嘛。

在界面中还有个UISwitch,这个是用来开启关闭dim tint的功能,其对应处理方法如下:

@IBAction func dimTimtHandler(sender: AnyObject) {
if let isOn = self.dimTintSwitch?.on { self.view.tintAdjustmentMode = isOn ? .Dimmed : .Normal
} updateViewConstraints()
}

当tintAdjustmentMode设置Dimmed时,其实际的效果是整个色值都变暗(此处无图可盗)。

另外,我们在子视图CustomView中重写了tintColorDidChange方法,以监听tintColor的变化,以更新我们的自定义视图,其实现如下:

 
override func tintColorDidChange() {
tintColorLabel.textColor = self.tintColor
tintColorBlock.backgroundColor = self.tintColor
}

所以方框和”Tint color label”颜色是跟着子视图的tintColor来变化的,而子视图的tintColor又是继承自父视图的。

在这个示例中,比较有意思的是还是对图片的处理。对图像的处理比较简单粗暴,对一个像素而言,如果它的alpha值为1的话,就将它的颜色设置为tint color;如果不为1的话,则设置为透明的。示例中的忍者头像就是这么处理的。不过我们需要设置图片的imageWithRenderingMode属性为AlwaysTemplate,这样渲染图片时会将其渲染为一个模板而忽略它的颜色信息,如代码所示:

 
var shinobiHead = UIImage(named: "shinobihead")
// 设置渲染模式
shinobiHead = shinobiHead?.imageWithRenderingMode(.AlwaysTemplate)

题外话

插个题外话,跟主题关系不大。

在色彩理论(color theory)中,一个tint color是一种颜色与白色的混合。与之类似的是shade color和tone color。shade color是将颜色与黑色混合,tone color是将颜色与灰色混合。它们都是基于Hues色调的。这几个色值的效果如下图所示:

一些基础的理论知识可以参考Hues, Tints, Tones and Shades: What’s the Difference?或更专业的一些文章。

小结

如果我们想指定整个App的tint color,则可以通过设置window的tint color。这样同一个window下的所有子视图都会继承此tint color。

当弹出一个alert或者action sheet时,iOS7会自动将后面视图的tint color变暗。此时,我们可以在自定义视图中重写tintColorDidChange方法来执行我们想要的操作。

有些复杂控件,可以有多个tint color,不同的tint color控件不同的部分。如上面提到的UIProgressView,又如navigation bars, tab bars, toolbars, search bars, scope bars等,这些控件的背景着色颜色可以使用barTintColor属性来处理。

参考

PS:文章转载自CocoaChina

http://www.cocoachina.com/ios/20150703/12363.html

详解 UIView 的 Tint Color 属性的更多相关文章

  1. input表单的type属性详解,不同type不同属性之间区别

    目标:详解表单input标签type属性常用的属性值 一.input标签和它的type属性 PS:input 元素可以用来生成一个供用户输入数据的简单文本框. 在默认的情况下, 什么样的数据均可以输入 ...

  2. 高效开发之SASS篇 灵异留白事件——图片下方无故留白 你会用::before、::after吗 link 与 @import之对比 学习前端前必知的——HTTP协议详解 深入了解——CSS3新增属性 菜鸟进阶——grunt $(#form :input)与$(#form input)的区别

    高效开发之SASS篇   作为通往前端大神之路的普通的一只学鸟,最近接触了一样稍微高逼格一点的神器,特与大家分享~ 他是谁? 作为前端开发人员,你肯定对css很熟悉,但是你知道css可以自定义吗?大家 ...

  3. AngularJS语法基础及数据绑定——详解各种数据绑定指令、属性应用

    AngularJS简单易学,但是功能强大.特别是在构建单页面应用方面效果显著.而 数据绑定 可以说是他被广泛使用的最主要的优点.他舍弃了对DOM的操作方式,一切都由AngularJS来自动更新视图,我 ...

  4. spring sessionFactory 属性配置详解,applicationContext中各种属性详解

    1.Bean的id为sessionFactory,对应的类为AnnotationSessionFactory,即采用注解的形式实现hibernate. 2.hibernateProperties,配置 ...

  5. 详解UIView的frame、bounds和center属性

    From: http://ios.wpjam.com/2011/08/29/uiview-frame-bounds-center/ 1.概要 翻开ios官方开发文档,赫然发现上面对这三个属性的解释如下 ...

  6. iOS学习--详解UIView的 contentStretch属性

    通过实例和图片理解UIView的contentStretch属性 方法 通过一个图片建立一个简单的UIImageView 设置它的contentStretch属性 修改它的frame属性 观察 测试用 ...

  7. XSD详解二 - 简易元素、属性、内容限定

    一.XSD 简易元素 XML Schema 可定义 XML 文件的元素. 简易元素指那些只包含文本的元素.它不会包含任何其他的元素或属性. 1.什么是简易元素? 简易元素指那些仅包含文本的元素.它不会 ...

  8. attrs.xml中declare-styleable 详解(用于自定义控件的属性)

    1. 框架定义: <declare-styleable name = "名称"> <attr name = "……" format = &qu ...

  9. 详解html中的marquee属性

    转自:https://www.jb51.net/web/531309.html 该标签不是HTML3.2的一部分,并且只支持MSIE3以后内核,所以如果你使用非IE内核浏览器(如:Netscape)可 ...

随机推荐

  1. 2014.3.4-C语言学习小结

    位操作: 知识点: 1.位运算符 2.位移运算符 1.将指定位设置为12.将指定位设置为03.获取指定位的内容 ==========================复习二进制 1.二进制转换 10-- ...

  2. 在Linux使用GCC编译C语言共享库

    在Linux使用GCC编译C语言共享库 对任何程序员来说库都是必不可少的.所谓的库是指已经编译好的供你使用的代码.它们常常提供一些通用功能,例如链表和二叉树可以用来保存任何数据,或者是一个特定的功能例 ...

  3. 《C++游戏开发》笔记十三 平滑过渡的战争迷雾(一) 原理:Warcraft3地形拼接算法

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9611887 作者:七十一雾央 新浪微博:http:/ ...

  4. 冒泡动画按钮的简单实现(使用CSS3)

    冒泡动画按钮的简单实现(使用CSS3) 原始的参考文章是 http://tutorialzine.com/2010/10/css3-animated-bubble-buttons/ ,基本原理是利用了 ...

  5. EF如何操作内存中的数据和加载外键数据:延迟加载、贪婪加载、显示加载

    EF如何操作内存中的数据和加载外键数据:延迟加载.贪婪加载.显示加载 之前的EF Code First系列讲了那么多如何配置实体和数据库表的关系,显然配置只是辅助,使用EF操作数据库才是每天开发中都需 ...

  6. 使用ServletContextListener和HttpSessionListener两种监听器实现记录当前网站在线人数

    web.xml中配置: <listener>    <listener-class>com.mcm.listener.ServletContextListenerImpl< ...

  7. 使用Excel背单词-高效-简单

    背单词是一个很纠结的事,想必那些走在留学路上的很多人都被英语这一关卡住了,这里,笔者就聊聊,不讲背单词的方法,只提供使用vb开发的产品和使用方法,有问题欢迎讨论. 简介:使用excel背单词,有一些人 ...

  8. icon 图标下载

    1. http://www.easyicon.net/ 2.http://www.iconpng.com/

  9. Python爬虫小白入门(五)PhatomJS+Selenium第二篇

    一.前言 前文介绍了PhatomJS 和Selenium 的用法,工具准备完毕,我们来看看如何使用它们来改造我们之前写的小爬虫. 我们的目的是模拟页面下拉到底部,然后页面会刷出新的内容,每次会加载10 ...

  10. web开发技术中Servlet技术的概述

    1.servlet是什么:servlet是一个位于服务器端的java应用程序它可以像jsp一样,直接输出信息 servlet类必须继承HttpServlet类,否则,不能称为serlvet servl ...