如何修改系统控件

多数情况下, 系统原生控件太丑, 无法满足我们的需求. 那么系统控件如何修改呢?
思路:

  • 找到你所需要更改的内容
  • 使用KVC赋值

需求: 更改badgeValue的系统背景图片

背景图片太丑, 我要更换

查看视图层级结构, 找到其View对应的位置
_UIBadgeBackground就是我们要找的背景图

那么接下来我们的任务是一层一层剥开它的心

取出要更改的控件

for tabBarChild in (self.tabBarController?.tabBar.subviews)! {
            print(tabBarChild)
}

从打印结果中找到我们需要的下一层 UITabBarButton

for tabBarChild in (self.tabBarController?.tabBar.subviews)!{
            if tabBarChild.isKindOfClass(NSClassFromString("UITabBarButton")!){
                print(tabBarChild)
            }
        }

打印结果为:

这里写图片描述

下一步目标为_UIBadgeView, 所以我们继续遍历

for tabBarChild in (self.tabBarController?.tabBar.subviews)!{
            if tabBarChild.isKindOfClass(NSClassFromString("UITabBarButton")!){
                for tabBarButtonChild in tabBarChild.subviews {
                    if tabBarButtonChild.isKindOfClass(NSClassFromString("_UIBadgeView")!){
                        print(tabBarButtonChild)
                    }
                }
            }
        }

打印结果为:
这里写图片描述

下一步目标: _UIBadgeBackground

for tabBarChild in (self.tabBarController?.tabBar.subviews)!{
            if tabBarChild.isKindOfClass(NSClassFromString("UITabBarButton")!){
                for tabBarButtonChild in tabBarChild.subviews {
                    if tabBarButtonChild.isKindOfClass(NSClassFromString("_UIBadgeView")!){
                        for badgeViewChild in tabBarButtonChild.subviews {
                            if badgeViewChild.isKindOfClass(NSClassFromString("_UIBadgeBackground")!){
                                print("终于等到你,还好没放弃\(badgeViewChild)")
                            }
                        }
                    }
                }
            }
        }

给控件赋值

想要赋值, 属性点不出来怎么办? 使用KVC
KVC: 知道Value不知道key怎么办? 使用运行时

运行时可以获取一个对象身上的成员变量

// 用于记录获取回来的成员变量是有多少个
var count: UInt32 = 0
// 通过运行时候,获取其身上的成员变量
// 参数1:传入 class,参数2: 传入一个指针,记录个数
let ivars = class_copyIvarList(NSClassFromString("_UIBadgeBackground")!, &count)

// 遍历成员变量的列表
for i in 0..// 取到对应位置的值
           let ivar = ivars[Int(i)]
           // 获取其名字
           let name = ivar_getName(ivar)
           let type = ivar_getTypeEncoding(ivar)
           // 转 NSString
           let nameString = NSString(CString: name, encoding: NSUTF8StringEncoding)
           let typeString = NSString(CString: type, encoding: NSUTF8StringEncoding)
           printLog("\(nameString)====\(typeString)")

           // 判断其对应属性, 通过 kvc 赋值其值
           if nameString!.isEqualToString("_image"){
            badgeViewChild.setValue(UIImage(named: "main_badge"), forKey: (nameString as! String))
}

注: 关键点在如何获取成员变量列表;
运行时有木有好强大

你可能感兴趣的:(控件,运行时)