Swift 系统控件常用扩展

本文主要是针对一些系统的控件进行扩展
下面简单介绍一些常用的方法,代码在后面

HWTextView

为TextView 添加占位文字
使用方法一:代码创建

   let tv = HWTextView()
   tv.frame = CGRect.init(x: 100, y: 100, width: 100, height: 100)
   tv.placeholder = "请输入"
   self.view.addSubview(tv)

使用方法二:Xib中使用

1.xib中修改Class类型(如下图)
2.设置placeholder 即可
 override func awakeFromNib() {
         tv.placeholder = "请输入"
    }
image.png
UIColor+HWExtension介绍
方法:HWColorWithHexString(hex:String,alpha:CGFloat)  
说明:16进制转颜色  hex: 16进制 alpha:透明度
使用:UIColor.HWColorWithHexString(hex: "29D8A5", alpha: 1)
UIView+HWExtension介绍
方法:addRounded(radius:CGFloat)
说明:添加圆角  radius: 圆角半径
使用:view.addRounded(radius: view. height/2)
方法:addBorder(width : CGFloat)
         addBorder(width : CGFloat, borderColor : UIColor)
说明:添加边框 width: 边框宽度  borderColor:边框颜色(没有默认是黑色)
使用: addBorder(width: 1)
UIButton+HWExtension介绍
方法:init(setImage:String, frame:CGRect, action: @escaping buttonClick)
说明:快速创建按钮 setImage: 图片名 frame:frame action:点击事件的回调
使用:
      let btn = UIButton.init(setImage:  "相机icon", frame: CGRect.init(x: 0, y: 0, width: 44, height: 44),action: {
            ...// 点击按钮的回调
      })
方法:countDown(count: Int,countDownBgColor:UIColor)
说明:倒计时 count:多少秒 countDownBgColor:倒计时背景颜色
使用:btn.countDown(count: 30, countDownBgColor: 你想要点颜色)
UIViewController+HWExtension介绍
方法:pushSetController(name:String)
说明:快速push到指定控制器 name:控制器名 
使用:self.pushController(name:"你要跳转的控制器名字")
方法:popToViewController(name:String)
说明:快速返回指定的控制器 name:要返回的控制器名 (注意:要返回的控制器必须在navigationController的子控制器数组中)
使用: popToViewController(name:"你要返回的控制器名字")
方法:setNavigationBarBackgroundColor(colorHex: String)
说明:修改导航栏的背景颜色 colorHex:颜色的16进制
使用: 
    override func viewWillAppear(_ animated: Bool) {
        setNavigationBarBackgroundColor(colorHex: "9AE6A9")
    }
    override func viewWillDisappear(_ animated: Bool) {
        setNavigationBarBackgroundColor(colorHex: "29D8A5")
    }

代码区

UIColor+HWExtension 实现

import UIKit

extension UIColor{
    /// 16进制转颜色  hex: 16进制 alpha:透明度
    class func HWColorWithHexString(hex:String,alpha:CGFloat) -> UIColor {
        var cString = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased()
        if cString.hasPrefix("#") {
            let index = cString.index(after: cString.startIndex)
            cString = cString.substring(from: index)
        }
        if cString.characters.count != 6 {
            return UIColor.black
        }
        let rRange = cString.startIndex ..< cString.index(cString.startIndex, offsetBy: 2)
        let rString = cString.substring(with: rRange)
        let gRange = cString.index(cString.startIndex, offsetBy: 2) ..< cString.index(cString.startIndex, offsetBy: 4)
        let gString = cString.substring(with: gRange)
        let bRange = cString.index(cString.startIndex, offsetBy: 4) ..< cString.index(cString.startIndex, offsetBy: 6)
        let bString = cString.substring(with: bRange)
        var r:CUnsignedInt = 0, g:CUnsignedInt = 0, b:CUnsignedInt = 0
        Scanner(string: rString).scanHexInt32(&r)
        Scanner(string: gString).scanHexInt32(&g)
        Scanner(string: bString).scanHexInt32(&b)
        return UIColor(red: CGFloat(r)/255.0, green: CGFloat(g)/255.0, blue: CGFloat(b)/255.0, alpha: alpha)      
    }
}

UIView+HWExtension实现

import UIKit

public extension UIView{
    // MARK: - 尺寸相关
    var x:CGFloat{
        get{
            return self.frame.origin.x
        } set{
            self.frame.origin.x = newValue
        }
    }
    
    var y:CGFloat{
        get{
            return self.frame.origin.y
        }set{
            self.frame.origin.y = newValue
        }
    }
    
    var width:CGFloat{
        get{
            return self.frame.size.width
        }set{
            self.frame.size.width = newValue
        }
    }
    
    var height:CGFloat{
        get{
            return self.frame.size.height
        }set{
            self.frame.size.height = newValue
        }
    }
    
    var size:CGSize{
        get{
            return self.frame.size
        }set{
            self.frame.size = newValue
        }
    }
    var centerX:CGFloat{
        get{
            return self.center.x
        }set{
            self.centerX = newValue
        }
    }
    var centerY:CGFloat{
        get{
            return self.center.y
        }set{
            self.centerY = newValue
        }
    }
    // MARK: - 尺寸裁剪相关
    /// 添加圆角  radius: 圆角半径
    func addRounded(radius:CGFloat) {
        self.layer.cornerRadius = radius
        self.layer.masksToBounds = true
    }
    /// 添加部分圆角(有问题右边且不了) corners: 需要实现为圆角的角,可传入多个 radius: 圆角半径
    func addRounded(radius:CGFloat, corners: UIRectCorner) {
        let maskPath = UIBezierPath.init(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize.init(width: radius, height: radius))
        let maskLayer = CAShapeLayer()
        maskLayer.frame = self.bounds
        maskLayer.path = maskPath.cgPath
        self.layer.mask = maskLayer;
    }

    // MARK: - 添加边框
    /// 添加边框 width: 边框宽度 默认黑色
    func addBorder(width : CGFloat) { // 黑框
        self.layer.borderWidth = width;
        self.layer.borderColor = UIColor.black.cgColor;
    }
    /// 添加边框 width: 边框宽度 borderColor:边框颜色
    func addBorder(width : CGFloat, borderColor : UIColor) { // 颜色自己给
        self.layer.borderWidth = width;
        self.layer.borderColor = borderColor.cgColor;
    }
    // 添加圆角和阴影
    func addRoundedOrShadow(radius:CGFloat)  {
        self.layer.cornerRadius = radius
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowOpacity = 0.1 // 不透明度
        self.layer.shadowOffset = CGSize(width: 0, height: 0)
        self.layer.shadowRadius = 1
        self.layer.masksToBounds = false
    }
}

UIButton+HWExtension(使用RxSwift来监听按钮点击事件的)

故需要pod 'RxSwift' #响应式编程库

import UIKit
import RxSwift

// MARK: - 快速设置按钮 并监听点击事件
private var disposeBag = DisposeBag()
typealias buttonClick = (()->()) // 定义数据类型(其实就是设置别名)
extension UIButton{
    /// 快速创建按钮 setImage: 图片名 action:点击事件的回调
    convenience init(setImage:String, action:@escaping buttonClick){
        self.init()
        self.frame = frame
        self.setImage(UIImage(named:setImage), for: UIControlState.normal)
        self.rx.tap.subscribe({ _ in
                action()
        }).disposed(by: disposeBag)
        self.sizeToFit()
    }
    convenience init(titleString:String, action:@escaping buttonClick){
        self.init()
        self.frame = frame
        self.setTitle(titleString, for: .normal)
        self.rx.tap.subscribe({ _ in
            action()
        }).disposed(by: disposeBag)
        self.sizeToFit()
    }
    /// 快速创建按钮 setImage: 图片名 frame:frame action:点击事件的回调
    convenience init(setImage:String, frame:CGRect, action: @escaping buttonClick){
        self.init( setImage: setImage, action: action)
        self.frame = frame
    }
    /// 快速创建按钮 titleString:title  frame:frame action:点击事件的回调
    convenience init(titleString:String, frame:CGRect, action: @escaping buttonClick){
        self.init(titleString: titleString, action: action)
        self.frame = frame
    }
}

// MARK: - 倒计时
extension UIButton{
    // MARK:倒计时 count:多少秒 默认倒计时的背景颜色gray
    /// 倒计时 count:多少秒 默认倒计时的背景颜色gray
    public func countDown(count: Int){
       self.countDown(count: count, countDownBgColor: UIColor.gray)
    }
    // MARK:倒计时 count:多少秒 countDownBgColor:倒计时背景颜色
    /// 倒计时 count:多少秒 countDownBgColor:倒计时背景颜色
    public func countDown(count: Int,countDownBgColor:UIColor){
        // 倒计时开始,禁止点击事件
        isEnabled = false
        // 保存当前的背景颜色
        let defaultColor = self.backgroundColor
        // 设置倒计时,按钮背景颜色
        backgroundColor = countDownBgColor
        var remainingCount: Int = count {
            willSet {
                setTitle("重新发送(\(newValue))", for: .normal)
                if newValue <= 0 {
                    setTitle("发送验证码", for: .normal)
                }
            }
        }
        // 在global线程里创建一个时间源
        let codeTimer = DispatchSource.makeTimerSource(queue:DispatchQueue.global())
        // 设定这个时间源是每秒循环一次,立即开始
        codeTimer.schedule(deadline: .now(), repeating: .seconds(1))
        // 设定时间源的触发事件
        codeTimer.setEventHandler(handler: {
            // 返回主线程处理一些事件,更新UI等等
            DispatchQueue.main.async {
                // 每秒计时一次
                remainingCount -= 1
                // 时间到了取消时间源
                if remainingCount <= 0 {
                    self.backgroundColor = defaultColor
                    self.isEnabled = true
                    codeTimer.cancel()
                }
            }
        })
        // 启动时间源
        codeTimer.resume()
    }
}

UIViewController+HWExtension实现

import Foundation
import UIKit
extension UIViewController {
    // MARK: - 设置相关
    /// 快速设置背景颜色
    func setBGColor() {
        weak var weakSelf = self // 弱引用
        weakSelf?.view.backgroundColor = HWBGColor()
    }
    func setBGColor(color:UIColor) {
        weak var weakSelf = self // 弱引用
        weakSelf?.view.backgroundColor = color
    }
    
    /// 快速设置title
    func setTitle(title:String) {
        weak var weakSelf = self // 弱引用
        weakSelf?.title = title
    }
    
    // MARK: - 跳转相关
    /// 快速push到指定控制器 name:控制器名
    func pushController(name:String) {
      _ = pushSetController(name: name)
    }
    
    func pushSetController(name:String) -> UIViewController {
         weak var weakSelf = self // 弱引用
        // 1.获取命名空间
        guard let clsName = Bundle.main.infoDictionary!["CFBundleExecutable"] else {
            return UIViewController()
        }
        // 2.通过命名空间和类名转换成类
        let cls : AnyClass? = NSClassFromString((clsName as! String) + "." + name)
        // swift 中通过Class创建一个对象,必须告诉系统Class的类型
        guard let clsType = cls as? UIViewController.Type else {
            return UIViewController()
        }
        // 3.通过Class创建对象
        let vc = clsType.init()
        weakSelf!.navigationController?.pushViewController(vc, animated: true)
        return vc
    }
    
    /// 快速返回指定的控制器 name:要返回的控制器名 (注意:要返回的控制器必须在navigationController的子控制器数组中)
    func popToViewController(name:String) { // 使用 self.popToViewController(name: "JYKMeViewController")
        weak var weakSelf = self // 弱引用
        // 1.获取命名空间
        guard let clsName = Bundle.main.infoDictionary!["CFBundleExecutable"] else {
            return
        }
        // 2.通过命名空间和类名转换成类
        let cls : AnyClass? = NSClassFromString((clsName as! String) + "." + name)
        // swift 中通过Class创建一个对象,必须告诉系统Class的类型
        guard (cls as? UIViewController.Type) != nil else {
            return
        }
        for  controller in (weakSelf!.navigationController?.viewControllers)! {
            if controller.isKind(of: cls!) {
                 weakSelf!.navigationController?.popToViewController(controller, animated: true)
            }
        }
    }
    /// 快速返回根的控制器
    func popToRootViewController() {
        weak var weakSelf = self // 弱引用
        weakSelf!.navigationController?.popToRootViewController(animated: true)
    }
    
    func presentController(name:String) {
        _ = presentSetController(name: name)
    }
    func presentSetController(name:String) -> UIViewController {
        // 1.获取命名空间
        guard let clsName = Bundle.main.infoDictionary!["CFBundleExecutable"] else {
            return UIViewController()
        }
        // 2.通过命名空间和类名转换成类
        let cls : AnyClass? = NSClassFromString((clsName as! String) + "." + name)
        // swift 中通过Class创建一个对象,必须告诉系统Class的类型
        guard let clsType = cls as? UIViewController.Type else {
            return UIViewController()
        }
        // 3.通过Class创建对象
        let vc = clsType.init()
        let nav = BBCNavigationController(rootViewController: vc)
        UIApplication.shared.keyWindow?.rootViewController?.present(nav, animated: true, completion: {
        })
        return vc
    }
    /// 修改导航栏的背景颜色 colorHex:颜色的16进制
    func setNavigationBarBackgroundColor(colorHex: String)  {
        navigationController?.navigationBar.setBackgroundImage(getImageWithColor(color: UIColor.HWColorWithHexString(hex: colorHex, alpha: 1)), for: UIBarPosition.any, barMetrics: UIBarMetrics.default)
        navigationController?.navigationBar.shadowImage = UIImage()
    }
}

代码:链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351