一、常规主题色使用点
应用在发布前都会对其主题色进行设置,以统一应用的风格(可能有多套主题)。在主题色设置上有几个方面,如下:
主题色的设置点,大体从上面四个方面着手,图片的主题色我们可通过图片更换的方式进行处理。而通过代码来处理的1-3条,有着不同的处理方法。大家常规处理方法如下:
步骤一:变化分离
1.利用Swift扩展语法扩展UIColor,将应用主题色在扩展中统一处理(适合单一主题色)
2.将主题色的配置写入文件中,由相应逻辑进行解析。此方法将主题色逻辑封装成主题色管理类(适合多套主题)
步骤二:离散使用上步封装的类
1.在任何使用主题色的地方,使用扩展中的UIColor方法来设置,一般包括背景色,文字颜色等
这里给出UIColor的扩展
1 extension UIColor { 2 3 //主题色 4 class func applicationMainColor() -> UIColor { 5 return UIColor(red: 238/255, green: 64/255, blue: 86/255, alpha:1) 6 } 7 8 //第二主题色 9 class func applicationSecondColor() -> UIColor { 10 return UIColor.lightGrayColor() 11 } 12 13 //警告颜色 14 class func applicationWarningColor() -> UIColor { 15 return UIColor(red: 0.1, green: 1, blue: 0, alpha: 1) 16 } 17 18 //链接颜色 19 class func applicationLinkColor() -> UIColor { 20 return UIColor(red: 59/255, green: 89/255, blue: 152/255, alpha:1) 21 } 22 23 }
二、TabBar主题色设置
很多应用中,默认情况下都使用了TabBar控件,但是TabBar主题色等设置根据使用情况的不同,设置起来也不一样。代码创建比较灵活,更改主题色比较容易。而使用了Xib/Storyboard也是有办法做统一处理的,如下,迭代更改TabBar默认字体颜色
1 func configTabBar() { 2 let items = self.tabBar.items 3 for item in items as [UITabBarItem] { 4 let dic = NSDictionary(object: UIColor.applicationMainColor(), 5 forKey: NSForegroundColorAttributeName) 6 item.setTitleTextAttributes(dic, 7 forState: UIControlState.Selected) 8 } 9 }
设置TabBar图片及文字默认选中颜色
self.tabBar.selectedImageTintColor = UIColor.applicationMainColor()
Tips注意事项
在一些情况,正常状态为白色图片时,真机测试时,白色图片会出现偏色(显示结果为灰色),这是因为系统默认着色导致的,在创建UITabBarItem时,可通过使用UIImageRenderingModeAlwaysOriginal避免。示例代码如下:
1 let imageNormal = UIImage(contentsOfFile: "imageNormal")?. 2 imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal) 3 let imageSelected = UIImage(contentsOfFile: "imageSelected") 4 let tabBarItem = UITabBarItem(title: "title", 5 image: imageNormal, 6 selectedImage: imageSelected)
三、一劳永逸,利用Hook原理通设NavigationBar颜色
IOS应用中,NavigationBar十分常用,它的使用主要包括以下两个场景
如果是纯代码构建的时候,比较简单,直接使用UIColor的扩展来设置颜色。实际项目中,有些界面是通过Xib/Storyboard来创建的,有些是代码写的,但这也难不到大家,使用继承。创建一个继承自UINavigationController的子类,通过这个子类来统一设置主题色。然后告诉项目中的所有人,强制使用UINavigationController子类,包括Xib/Storyboard等。问题是旧项目怎么办,这种强制要求可以工作,有没有一个更好的办法,让所有人正常使用UINavigationController,而在神不知鬼不觉的情况下,通设所有NavigationBar呢? 先上代码,再解释
1.创建一个UIViewController的扩展
1 extension UIViewController { 2 func viewDidLoadForChangeTitleColor() { 3 self.viewDidLoadForChangeTitleColor() 4 if self.isKindOfClass(UINavigationController.classForCoder()) { 5 self.changeNavigationBarTextColor(self as UINavigationController) 6 } 7 } 8 9 func changeNavigationBarTextColor(navController: UINavigationController) { 10 let nav = navController as UINavigationController 11 let dic = NSDictionary(object: UIColor.applicationMainColor(), 12 forKey:NSForegroundColorAttributeName) 13 nav.navigationBar.titleTextAttributes = dic 14 nav.navigationBar.barTintColor = UIColor.applicationSecondColor() 15 nav.navigationBar.tintColor = UIColor.applicationMainColor() 16 17 } 18 19 }
2.编写用于Hook的工具类
1 func swizzlingMethod(clzz: AnyClass, #oldSelector: Selector, #newSelector: Selector) { 2 let oldMethod = class_getInstanceMethod(clzz, oldSelector) 3 let newMethod = class_getInstanceMethod(clzz, newSelector) 4 method_exchangeImplementations(oldMethod, newMethod) 5 }
3.在AppDelegate中调用
1 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { 2 swizzlingMethod(UIViewController.self, 3 oldSelector: "viewDidLoad", 4 newSelector: "viewDidLoadForChangeTitleColor") 5 //do others 6 return true 7 }
4.原理说明
在程序入口处,通过运行时机制,动态的替换UIViewController的周期方法viewDidLoad为我们指定的方法viewDidLoadForChangeTitleColor。在viewDidLoadChangeTitleColor中,需要做两件事:
调用原来的viewDidLoad方法
执行修改主题色相关代码
1.如何调用原来的viewDidLoad方法
在AppDelegate中,通过调用方法swizzlingMethod我们将viewDidLoad与viewDidLoadForChangeTitleColor方法体进行了替换,原理如下图:
从上面的图可以看出,当在viewDidLoadForChangeTitleColor中执行:
是不会造成循环调用,反而是调用了我们期望执行的viewDidLoad方法体。
四、Xib/Storyboard的处理
一些在Xib/Storyboard中设置的主题色,比如文本颜色,按钮的高亮颜色等,该如何处理呢,以UILabel为例,建立扩展
1 extension UILabel { 2 var colorString: String { 3 set(newValue) { 4 switch newValue { 5 case "main": 6 self.textColor = UIColor.applicationMainColor() 7 case "second": 8 self.textColor = UIColor.applicationSecondColor() 9 case "warning": 10 self.textColor = UIColor.applicationWarningColor() 11 default: 12 self.textColor = UIColor.applicationSecondColor() 13 } 14 } 15 get { 16 return self.colorString 17 } 18 } 19 }
在Xib/Storyboard的查检器中进行编辑,如下图:
4.总结