声明:本文译自《NSHipster》
风格 vs. 实质,信息 vs. 媒介,言辞 vs. 逻辑。
美丽仅是肤浅的表面,还是更深层的事实?某个事物有好的设计意味着什么?审美的判断是绝对的,还是因人而异的?
这些是哲学家、艺术家、创作者千年来反复思索的深刻问题。
当我们都继续着对宇宙中美和真理的追求,APP 销售市场清晰印证了以下的话:
用户会为好看的软件付出更多的钱。
当一个人买下一台 iPhone,他其实买的是苹果公司的哲学:好用的东西同时可以很好看。当我们选择为 iOS 平台开发应用时,我们也是抱着同样的信念。一套稀烂的 UI 反映了其下糟糕的代码。
曾经在 iOS 平台上,使用像方法调剂(Method Swizzling)这样的技术来实现 UI 个性化,绕过 AppStore 的上架审核。幸运的是,随着 iOS 5 的改变,开发者有更简单的方法来实现:UIAppearance
.
Getting Started
UIAppearance
使得视图和控件的外观在整个 App 范围内统一定义。
为了在 UIKit 既有的架构中做到以上的效果, Apple 采取了一个聪明的方案:UIAppearance
是一个协议,返回一个代理(proxy),它会转发任意配置到特定类的实例。为什么使用 proxy 而不是 UIView 的一个属性(property)或者方法(method)呢?因为有一些不是 UIView 的类,如UIBarButtonItem
,也会渲染它们的复合视图。Appearance 可以对所有实例进行个性化,或者应用到特定的视图层次范围中。
+appearance
: 为接受者返回 appearance 代理。+appearanceWhenContainedIn:(Class<UIAppearanceContainer>)ContainerClass,...
: 为在指定容器层次中的接受者返回 appearance 代理。
为了个性化每个类的实例的外观,你可以用appearance()
得到对应类的 appearance 代理。举个例子,修改所有 UINavigationBar 实例的默认颜色:
1 | [[UINavigationBar appearance] setTintColor:myColor]; |
某些实例类可能包含在容器类的实例中或者层次化的实例中,为了个性化它的外观,可以使用appearanceWhenContainedInInstancesOfClasses(_:)
来得到这个类的 appearance 代理。
1 | [[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UINavigationBar class]]] |
决定哪些属性对UIAppearance
生效
UIAppearance
代理有一个主要缺陷,就是很难判断哪些选择子是兼容的。在 iOS 7 的改进中,UIAppearance
现在返回instancetype
,允许代码补全以我们期待的方式出现。太好了!
为了找出哪些方法可以和UIAppearance
配合,我们进入头文件看一看:
1 | $ cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/System/Library/Frameworks/UIKit.framework/Headers |
UIAppearance
在方法签名(method signatures)中寻找UI_APPEARANCE_SELECTOR
宏。任何带有这个注释的方法可以和 appearance 代理一起使用。
在自定义 UIView 的子类中实现
NSLocalizedString
和#pragma
是 Objective-C 代码质量的标志,相同地,自定义的 UI 类去遵从UIAppearance
协议,不仅是一个最佳实践,更在实现代码中展示了一定水平的谨慎。
任何渴望出色地实现自己的开源 UI 组件的开发者,都一定要读这篇牛叉的文章,它描述了一些在自定义视图中实现UIAppearance
的过程中要注意的要点。
另外的选择
UIAppearance
另外的一个缺陷是它的样式规则是强制启用的,而不是声明的。这就是说,样式的应用是在运行时,而不是靠一系列样式规则解释而来。
如果说这是从 Web 开发借鉴思想,是内容和表现的分离,说出对 CSS 你想说的吧,但是 stylesheets 是美妙的。
iOS 开发者中的 stylesheet 爱好者现在有一些选择。Pixate是一个使用 CSS 风格化应用的商业框架。NUI,是一个Tom Benner的开源项目,和 CSS / SCSS 类的语言做同样的事。另外一个Robert Wijas的开源项目UISS,可以从 JSON 中读取UIAppearance
的规则。