UIView并没想的那么简单 - tintColor揭秘

这篇文章针对新手向 iOS 玩家, 请老鸟自行飘过_
目前很多 iOS 新手都是通过拖拖控件, 搞搞 UI 这种方式入门的, 毕竟直观易懂, What You See Is What You Get 的方式也很容易接受, 降低入门门槛. 可凡事都要辩证地看, 正是这种相对容易的学习方式会令你忽略很多东西.
闲话不多啥, 直接进入主题!


首先让我们回到最初的起点, 回到那最单纯的开始. 在一个新建的 Single View Application 的空白 Main.storyboard 中拖入一个 UIButton, 好了, 大功告成! 成果如下:



你确定这不是在逗我? 这有什么好说的!!!
那么问题来了! 为什么"Button"这几个字是蓝色的?
你可能会说, 这是系统设定的, 跟我有什么关系? Alright! Alright! 现在来点儿更有趣的, 我们为这个 Button 加一个 image, 注意, 不是 backgroundImage.
这个要加载的 image 原来长成这个样子, 见下图:



如果显示器不偏色的话, 你看到的应该是一张黑色的图片. 可是, 把它设置为 Button 的 image 后, 居然变成这个样子了:

你可能会说, 我的明明是这样的啊:



朋友, 当心! 通过 storyboard 为 Button 设置 image 属性后, 这个 Button 的 Type 属性会变为 Custom, 把它改回 System 就变成蓝色的了.
细心的你可能已经发现了, 这个 Button 的 Type 至关重要啊, 直接影响 Button 会长成什么样子. 没错, Type 为 System 时, Button 就会受某些系统参数的影响, 那到底是系统的什么东西在影响着 Button 的样子呢?

我们的主角终于要正式登场啦! 这个会对 Button 的样子产生影响的所谓的"系统的东西"就是 tintColor, 这是一个 UIColor 类型的属性. 这个词儿怎么翻译? 算了, 还是不要纠结翻译的问题了, 就直接称呼它的英文名吧...
先来一个粗略的认识, 大家可以认为系统默认的 tintColor 就是蓝色的, 于是乎整个 App 中采用 System 类型的 Button 就都变蓝了. 其实, 受其影响的还不只 UIButton, 回想一下, 你创建的 navagation controller 和 tabbar controller, 是不是导航栏里的东西默认都是蓝色的? 还有 slider 在滑动时露出的部分也是蓝色的? 还有一些其他的控件也受其影响, 这里不再赘述了.
看来, 我们终于逮到了这个所谓的"系统级别"的元凶! 那问题来了, 凭什么我就一定要用系统设定好的蓝色? 我就是要改成别的颜色, 怎么办? 显然对每个控件都进行自定义是不现实的. 没错, Xcode 确实提供了毕其功于一役的利器. 如果你是用 storyboard 创建界面的, 那么只要在入口控制器的 File Inspector 中修改一下 Global Tint 即可, 见下图:



修改一下试试吧, 是不是你的所有控件都变色了? 就这么简单!


问题又来了, 如果不通过 storyboard 的方式来加载界面, 而是通过纯代码的方式来实现界面的要怎么办? 至此, 终于要开始探究 tintColor 最有趣的部分了!
不知道大家有没有仔细查看头文件, tintColor 是 iOS7.0 引入的一个 UIView 的属性. 再来强调一下, tintColor 是 UIView 的属性!!! 虽然没有说三遍, 但这一点非常重要! 这就意味着, 所有的 UI 控件都有 tintColor 这个属性! 可是我们平时也没注意到这个东西啊, 这是怎么回事儿?
其实, tintColor 这个东西非常神奇, 它具有继承, 重写, 传播的特点.

  • 继承
    只要一个 UIView 的 subview 没有明确指定 tintColor, 那么这个 view 的 tintColor 就会被它的 subview 所继承! 在一个 App 中, 最顶层的 view 就是 window, 因此, 只要修改 window 的 tintColor, 那么所有 view 的 tintColor 就都会跟着改变.(这种说法其实并不严谨, 请耐心继续看下去_)
  • 重写
    如果明确指定了某个 view 的 tintColor, 那么这个 view 就不会继承其 superview 的 tintColor, 而且自此, 这个 view 的 subview 的 tintColor 会发生改变.
  • 传播
    一个 view 的 tintColor 的改变会立即向下传播, 影响其所有的 subview, 直至它的一个 subview 明确指定了 tintColor 为止.

感觉上述三点读起来像绕口令有没有? 不要担心, 通过下述例子, 希望可以帮你理清脉络.
首先在一个 ViewController 中加入三个普通的 UIView, 并且一一构成父子关系, 即 First View 的直接 subview 为 Second View, Second View 的直接 subview 为 Third View. 然后分别在三个 UIView 中加入三个类型为 System 的 UIButton, 即 First Button 是 First View 的 subview, 与整个 Second View 平级; Second Button 是 Second View 的 subview, 与整个 Third View 平级; Third Button 是 Third View 的 subview.



此时, 由于三个 UIView 的 tintColor 都没有明确指定, 那么它们的 tintColor 都会继承自最顶层的 view - window - 即蓝色. 好了, 既然三个 view 和三个 Button 都是 window 的 subview, 那么它们的 tintColor 就一并都变为了蓝色.
此时, 只要改变一下 window 的 tintColor, 效果就完全不一样了, 见下图:



怎么样? 这与在 storyboard 中修改 Global Tint 的效果是相同的. 同时, 这也证明了 tintColor 的改变是能够向下传播的. 想要达到这种效果还能怎么实现? 没错, 不需要修改 window 的 tintColor, 修改 First View 的 tintColor 也同样奏效! 因为 tintColor 的改变是向下传播的, 重要的事情说 N 遍!!
此时, 如果我们明确指定了 Second View 的 tintColor 会如何? 看看实际效果是不是与你设想的相同:

可以看到, First View 的 tintColor 的改变在 Second View 这一层停止传播了. 这就是 tintColor 的重写特点! 对 First View 来说, 它的 subview - Second View - 明确指定了 tintColor, 那么这个 Second View 就不会继承 First View 的 tintColor, 而是采用自己的 tintColor, 因此, 作为 Second View 的 subview - Second Button 以及整个 Third View - 的 tintColor 就都改变了.
最后, 如果明确指定了 Third View 的 tintColor, 那么你就会看到一个新的世界:



怎么样? 差不多理清 tintColor 的继承, 重写以及传播是怎么回事儿了吧.
总结一下就是: 对一个 view 来说, 只要它的 tintColor 没有明确指定, 那么它就会采用其 superview 的 tintColor. 一旦这个 view 的 tintColor 改变了, 这种改变就会一直向其 subview 传播, 直至某个 subview 明确指定了 tintColor 为止.
此外, 在某个 view 的 tintColor 发生改变时, 这个 view 以及它所有受影响的 subview 都会调用 tintColorDidChange 方法, 所以有什么自定义操作, 都可以在这个方法中进行.
好了, 希望大家利用 tintColor 的特点来打造五彩斑斓的界面吧!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容