利用Runtime修改UIdatePicker的字体颜色
- 用过苹果原生UIdatePicker的Ios开发者都知道,UIdatePicker这个时间选择器的字体颜色默认的是黑色,并且官方API并没有提供可以修改字体颜色的API。如下:
UIDatePicker *picker = [[UIDatePicker alloc] init];picker.datePickerMode = UIDatePickerModeDate;picker.maximumDate = [NSDate dateWithTimeIntervalSince1970:0];picker.minimumDate = [NSDate dateWithTimeIntervalSinceNow:10000];[picker setDate:[NSDate date]];
做到上面这个效果,我主要进行了如下步骤:
- 利用通过遍历UIDatePicker类的所有属性,包括写在.m文件中看不到的属性。
- 找到苹果用于修改字体颜色的属性使用rumtime动态修改。
unsigned int outCount;int i;objc_property_t *pProperty = class_copyPropertyList([UIDatePicker class], &outCount);for (i = outCount -1; i >= 0; i--){// 循环获取属性的名字 property_getName函数返回一个属性的名称NSString *getPropertyName = [NSString stringWithCString:property_getName(pProperty[i]) encoding:NSUTF8StringEncoding];NSString *getPropertyNameString = [NSString stringWithCString:property_getAttributes(pProperty[i]) encoding:NSUTF8StringEncoding];if([getPropertyName isEqualToString:@"textColor"]){[picker setValue:[UIColor whiteColor] forKey:@"textColor"];}NSLog(@"%@====%@",getPropertyNameString,getPropertyName);}
以上代码中pProperty返回的是一个所有属性的数组,通过循环遍历我发现@”textColor”这个属性应该就是我想要的属性,然后通过setValue赋值白色,最后就做到了上图的结果。
或许说干过两年ios开发的都知道这个东西,但是笔者更想表达的还是这种分析问题和处理问题并最终解决问题的思想,当我们修改系统原生控件遇到瓶颈的时候可以采用这种方法来学习这个控件更多的特性
如果你觉得不过瘾?那就继续吧,更刺激的还在后面呢~
本来这个地方做好之后,结果测试测出一个非常奇葩的bug,就是UIDatepicker在当天的字体仍然是黑色。
-如下图
看到了么,因为我在写这篇文章的时候是九月一号,所以九月一号的字体还是以前的黑色,比如说我动态改变系统日期为九月二号,它也会自动变成九月二号的字体是黑色,由于UI设计的是背景黑色,所以这里根本就看不清,严重影响产品体验。通过一系列的纠结,我最后发现,如果UIDatepicker设置了最大时间(maxDate)和最小时间(minDate)就会这样,如果不设置就不出现这种情况,但是需求要限制最大时间和最小时间。
在这个解决的过程中,我试过了遍历属性还有查看官方API都找不到任何资料,甚至都想不通苹果内部是怎么处理的这么牛逼的。
实在没办法,我到处百度还是没进展,最后我终于在国外的网站找老外解决了这个问题(老外为啥比国人要牛逼呢?)
解决这个问题的核心代码如下:
SEL selector = NSSelectorFromString(@"setHighlightsToday:");NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDatePicker instanceMethodSignatureForSelector:selector]];BOOL no = NO;[invocation setSelector:selector];[invocation setArgument:&no atIndex:2];[invocation invokeWithTarget:picker];
通过这个代码我不断的逆向推理其实现原理,并且各种百度查找NSInvocation的相关资料。
最后让我逐步来解析一下每一行代码的意思:
SEL selector =NSSelectorFromString(@”setHighlightsToday:”);
通过Runtime的NSSelectorFromString利用字符串获取方法@”setHighlightsToday:”(注意,看这个方法名就是今天的高亮显示开关,注意字符串后面的冒号,表示这个方法是有参数的)NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDatePicker instanceMethodSignatureForSelector:selector]];
用这个SEL创建UIdatepicker类的NSMethodSignature来创建一个NSInvocation。BOOL no = NO;
[invocation setSelector:selector];
[invocation setArgument:&no atIndex:2];
[invocation invokeWithTarget:picker];
给invocation设置参数,设置target,并且动态调用设置参数NO(苹果默认YES并且不开放)
其实NSInvocation也是Runtime的一种方式。
注意[invocation setArgument:&no atIndex:2];这个2是怎么来的,因为setArgument中第一个参数的类picker,第二个参数是SEL,所以我们自己的参数最小的数字就是2,也就是这个方法的第一个参数
最后问题彻底解决了,晒张截图求真相:
虽然问题是最终解决了,但是假如下次我们又遇到这种类似的问题应该怎么办呢?难道又要焦头烂额的到处寻求援助么?程序员的上进心和求学心哪里去了?
最后笔者花了一到两天的时间一直思考这个问题,并最终通过分析老外的解决方式逆向找到解决的具体原理
前面说过,可以通过NSString *getPropertyName = [NSString stringWithCString:property_getName(pProperty[i]) encoding:NSUTF8StringEncoding];来获取一个类所有的属性,最后我在Runtime的API中发现,也可以获取一个类所有的方法(有兴趣的可以去了解一下IMP指针)。
unsigned int outCount;int i;Method *method = class_copyMethodList([UIDatePicker class],&outCount);
也就是说,利用Rumtime遍历某个类的所有属性和所有的方法,苹果的API限制在我们面前形同虚设,可以解决更多的一些原生API不开放的东西,其实这里也可以自己重写,不过相当麻烦,而且会有复杂的内存问题,所以还是直接用Runtime绕过苹果限制修改原生控件简单的多
其实runtime本身的东西很少,更多的是一些概念性的东西,有兴趣的也可以去了解一下runtime,本文主要讲的是一种利用runtime去解决实际问题的思维方式。
欢迎大家转载学习并且指出笔者不到之处,转载请注明出处哈!
利用Runtime修改UIdatePicker的字体颜色相关推荐
- Solar-PuTTY修改背景、字体颜色和字体大小
Solar-PuTTY设置背景.字体颜色和字体大小 第一步.找到设置 第二步 第三部.这里是修改字体大小和字体类型 第四步.修改背景.字体颜色 第五步.保存(最重要)
- ios 系统状态栏样式修改_iOS_状态栏字体颜色修改(完美解决)
情况1:如何把所有界面的状态栏的字体颜色都设置为黑色 情况2:如何把所有界面的状态栏的字体颜色都设置为白色 如果所有的界面继承了一个共同的父类,可以使用下面的方法: 第一步:在info.plist中添 ...
- 如何修改max界面字体颜色?
大家好!小编是up主:基础建模 今天小编弄了个有趣的--修改字体颜色 主要是之前建模的时候,界面一般是白色字体,这样不方便观察或者找命令. 所以就想弄不同颜色字体,这样找起来就方便很多啦. 而且在视觉 ...
- python pandas怎么修改Excel表格字体颜色?
在pandas中,可以通过样式设置来修改Excel表格的字体颜色.具体步骤如下: 第一步,读取Excel表格数据到DataFrame: import pandas as pd df = pd.read ...
- 修改cmd控制台字体颜色,附C++代码
写程序修改cmd窗口字体颜色 代号 颜色 0 黑色 1 蓝色 2 绿色 3 浅绿色 4 红色 5 紫色 6 黄色 7 白色 8 灰色 9 淡蓝色 A/a 淡绿色 B/b 淡浅绿色 C/c 淡红色 D/ ...
- input框中颜色color修改了 但是字体颜色一直是默认灰色
输入框里面的颜色一直默认为灰色.加了颜色color,权重最高但是颜色还是默认灰色. 这是由于谷歌浏览器的自带样式的缘故.在样式中加个-webkit-text-fill-color: #1576DC;/ ...
- markPoint气泡大小及修改气泡中字体颜色
markPoint : { // symbolSize: 80,控制气泡大小 itemStyle:{ normal:{ ...
- Android 开发中动态修改StatusBar 的字体颜色(仅可以黑白)
在开发中,产品要实现一个点击搜索,然后改变statusbar的字体颜色,百度了一通,发现,有一个比较好的blog 可以实现该效果 ,正好可以实现该效果,不论如何先上效果图: 将工具类代码贴上来 这个方 ...
- 怎么设置linux系统字体颜色,如何修改linux系统字体颜色
2017-01-20 回答 方法一: 1.在~/.bash_profile文件中添加ls_colors export ls_colors='no=00:fi=00:di=01;33:ln=01;36: ...
最新文章
- java处理中文字符_Java中文字符处理的四大迷题
- 可以由指令直接指定的I/O端口数(一共256个,从0到255一共256个端口号)
- 210314阶段三VS使用Linux 的sqlite3 API
- 只要 8 个步骤,学会这个 Docker 命令终极教程!
- 暗黑破坏神java魔法护身,发个实用的贴!!暗黑+1+2技能护身符合成,望大家顶下,能加精...
- 取代上万行遗留代码,机器学习模型终“上位”
- FastStone Capture屏幕长截图
- 如何挑选蓝牙耳机,蓝牙参数说明
- 对赌协议的经典案例分析
- 卖身百度,是知乎最好的结局?
- word添加多个目录
- 研究生期间论文发表经验总结
- PHP网页输入年份查找生肖,vb十二生肖程序 根据年份的输入便可以查询到你是什么生肖...
- 新建SpringCloud电商后台项目
- 写在母亲节――5月8日的心情
- 生成微信公众号对应二维码的两种简单方法
- iPhone 手机修复屏幕划痕
- 山东科技大学计算机科学与技术学硕,2021年山东科技大学计算机科学与技术(081200)硕士研究生招生信息_考研招生计划和招生人数 - 学途吧...
- kali的网络设置及三种网络模式
- 【学习笔记】CSW网络目录服务
热门文章
- axure9 html文件使用ie打开图片无法显示_win7系统html文件如何打开 win7系统html文件打开方法【介绍】...
- c语言实现辗除法,辗除法什么东西哦?
- 十九、 彻底掌握金融量化交易库Talib
- 三十六、深入Vue.js组件Component(上篇)
- 博士申请 | 香港中文大学(深圳)罗元教授招收计算机与信息工程全奖博士
- PyPy为什么能让Python比C还快?一文了解内在机制
- CVPR 2019 | INIT:针对实例级的图像翻译
- AI识虫:林业病虫害数据集和数据预处理方法
- Python基础知识-优雅的with as语句
- Pycharm-列出代码结构