iOS swift 代理协议
swift中的代理实现和oc中是有区别的
protocol HXQLimitedTextFieldDelegate{
    func test()
}
代理中默认所有方法都是required,如果需要某个代理方法是可选的,则需要用下面的方法
@objc protocol HXQLimitedTextFieldDelegate: class{
    func test()
    @objc optional func test2()
}
如果需要代理有responds(to: <#T##Selector!#>)方法,则需要遵守协议
@objc protocol HXQLimitedTextFieldDelegate: NSObjectProtocol{
    func test()
    @objc optional func test2()
}
设置代理
weak var realDelegate: HXQLimitedTextFieldDelegate?  //这里需要用weak防止循环引用
附一段代码:(HXQLimitedTextField swfit版本)具体使用方法请参考:https://www.cnblogs.com/qqcc1388/p/7251117.html
HXQLimitedTextField能够快速实现以下功能(支持xib):
- 限制输入的字符(数字,字母,数字+字母,email等)
 - 提供一个可以监听textField实时改变的方法,不需要自己去写观察者
 - 限制输入文字的最大长度
 - 限制textField距离leftPading rightPading
 - 更方便快捷的设置leftView rightView
 - 设置placeholderColor
 
//
//  HXQLimitedTextField.swift
//  hxquan-swift
//
//  Created by Tiny on 2018/11/5.
//  Copyright © 2018年 hxq. All rights reserved.
//
import UIKit
enum HXQLimitedTextFieldType: Int {
    case normal = 0        //默认
    case number            //数字
    case numberOrLetter    //数字和字母
    case email             //数字 字母 和 特定字符( '.'  '@')
    case password          //数字 字母 下划线
}
let kLetterNum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
let kEmail = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
let kPassword = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"
@objc protocol HXQLimitedTextFieldDelegate: class{
    //为了防止 self.delegate = self 然后外部有重写了这个delegate方法导致代理失效的问题,这里重写一遍系统的代理方法
    //在使用HXQLimitedTextField的使用请不要使用UITextField本身代理方法
    //这里只是拓展了textField的部分代理,如果有需要还可以自己实现在这里添加
    /// 键盘return键掉用
    ///
    /// - Parameter textField: textField
    /// - Returns:
    @objc optional func limitedTextFieldShouldReturn(_ textField: HXQLimitedTextField) -> Bool
    /// 输入结束调用
    ///
    /// - Parameter textField: textField
    @objc optional func limitedTextFieldDidEndEditing(_ textField: HXQLimitedTextField)
    /// 输入开始调用
    ///
    /// - Parameter textField: textField
    @objc optional func limitedTextFieldDidBeginEditing(_ textField: HXQLimitedTextField)
    /// 输入内容改变调用(实时变化)
    ///
    /// - Parameter textField: textField
    @objc optional func limitedTextFieldDidChange(_ textField: HXQLimitedTextField)
    /// 输入开始启动的时候调用
    ///
    /// - Parameter textField: textField
    /// - Returns:
    @objc optional func limitedTextFieldShouldBeginEditing(_ textField: HXQLimitedTextField) -> Bool
}
class HXQLimitedTextField: UITextField {
    ///  代理方法 尽量使用这个代理而不是用textfield的代理
    weak var realDelegate: HXQLimitedTextFieldDelegate?
    /// HXQLimitedTextFieldType 根据type值不同 给出不同limited 默认HXQLimitedTextFieldTypeNomal
    var limitedType: HXQLimitedTextFieldType = .normal {
        didSet{
            if limitedType == .normal {
                keyboardType = .default
                filter = nil
            }else {
                keyboardType = .asciiCapable
                if limitedType == .number {
                    keyboardType = .numberPad
                    filter = nil
                }else if limitedType == .numberOrLetter {
                    filter = kLetterNum
                }else if limitedType == .email {
                    filter = kEmail
                }else if limitedType == .password {
                    filter = kPassword
                }
            }
        }
    }
    /// HXQTextField内容发生改变block回调
    var textFiledDidChange: ((String)->Void)?
    /// textField允许输入的最大长度 默认 0不限制
    var maxLength: Int = 0
    /// 给placeHolder设置颜色
    var placeholderColor: UIColor? {
        didSet{
            attributedPlaceholder = NSAttributedString(string:placeholder ?? "" ,attributes: [NSAttributedString.Key.foregroundColor : placeholderColor as Any])
//            setValue(placeholderColor, forKeyPath: "placeholderLabel.textColor")
        }
    }
    /// 距离左边的间距  默认10
    var leftPadding: CGFloat = 10 {
        didSet{
            setValue(leftPadding, forKey: "paddingLeft")
        }
    }
    /// 距离右边的间距  默认10
    var rightPadding: CGFloat = 10 {
        didSet{
            setValue(rightPadding, forKey: "paddingRight")
        }
    }
    /// textField -> leftView
    var customLeftView: UIView? {
        didSet{
            leftView = customLeftView
            leftViewMode = .always
        }
    }
    /// textField -> RightView
    var customRightView: UIView? {
        didSet{
            rightView = customRightView
            rightViewMode = .always
        }
    }
    fileprivate var filter: String?
    override init(frame:CGRect) {
        super.init(frame:frame)
        setup()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }
    func setup(){
        font = UIFont.systemFont(ofSize: 14)
        delegate = self
        textAlignment = .left
        addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
    }
}
extension HXQLimitedTextField: UITextFieldDelegate{
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        return realDelegate?.limitedTextFieldShouldReturn?(self) ?? true
    }
    func textFieldDidBeginEditing(_ textField: UITextField) {
        realDelegate?.limitedTextFieldDidBeginEditing?(self)
    }
    func textFieldDidEndEditing(_ textField: UITextField) {
        realDelegate?.limitedTextFieldDidEndEditing?(self)
    }
    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        return (realDelegate?.limitedTextFieldShouldBeginEditing?(self)) ?? true
    }
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        //超过最大长度 并且不是取消键被点击了
        if textField.text!.count > maxLength && maxLength > 0  && string != "" {
            return false
        }
        //没有筛选条件直接跳过
        if filter == nil {
            return true
        }
        //限制条件
        let cs = CharacterSet(charactersIn: filter!)
         //按cs分离出数组,数组按@""分离出字符串
        let filtered = string.components(separatedBy: cs ).joined(separator: "")
        return filtered == string
    }
    @objc func textFieldDidChange(_ textField: UITextField){
        realDelegate?.limitedTextFieldDidChange?(self)
        textFiledDidChange?(textField.text ?? "")
    }
    override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
        if #available(iOS 11.0, *)  {
            //如果是左对齐 则+leftPadding
            //右对齐      则-rightPadding
            //中间对其    则pading设置为0
            var padding: CGFloat = 0;
            if textAlignment == .right{
                padding = -rightPadding;
            }else if self.textAlignment == .left {
                padding = leftPadding;
            }
            let rect = CGRect(x: bounds.origin.x+padding, y: bounds.origin.y, width: bounds.size.width, height: bounds.size.height)
            return super.placeholderRect(forBounds: rect)
        }
        return super.placeholderRect(forBounds: bounds)
    }
}
												
											iOS swift 代理协议的更多相关文章
- iOS   swift的xcworkspace多项目管理(架构思想)
		
iOS swift的xcworkspace多项目管理(架构思想) 技术说明: 今天在这里分享 swift下的 xcworkspace多项目管理(架构思想),能为我们在开发中带来哪些便捷?能为我们对整 ...
 - iOS Swift 模块练习/swift基础学习
		
SWIFT项目练习 SWIFT项目练习2 iOS Swift基础知识代码 推荐:Swift学习使用知识代码软件 0.swift中的宏定义(使用方法代替宏) 一.视图 +控件 1.UIImag ...
 - ios swift 实现饼状图进度条,swift环形进度条
		
ios swift 实现饼状图进度条 // // ProgressControl.swift // L02MyProgressControl // // Created by plter on 7/2 ...
 - Building gRPC Client iOS Swift Note Taking App
		
gRPC is an universal remote procedure call framework developed by Google that has been gaining inter ...
 - iOS Swift WisdomScanKit图片浏览器功能SDK
		
iOS Swift WisdomScanKit图片浏览器功能SDK使用 一:简介 WisdomScanKit 由 Swift4.2版编写,完全兼容OC项目调用. WisdomScanKit的 ...
 - iOS Swift WisdomScanKit二维码扫码SDK,自定义全屏拍照SDK,系统相册图片浏览,编辑SDK
		
iOS Swift WisdomScanKit 是一款强大的集二维码扫码,自定义全屏拍照,系统相册图片编辑多选和系统相册图片浏览功能于一身的 Framework SDK [1]前言: 今天给大家 ...
 - iOS Swift WisdomHUD 提示界面框架
		
iOS Swift WisdomHUD 提示界面框架 Framework Use profile(应用简介) 一:WisdomHUD简介 今天给大家介绍一款iOS的界面显示器:WisdomHUD,W ...
 - iOS Swift WisdomKeyboardKing 键盘智能管家SDK
		
iOS Swift WisdomKeyboardKing 键盘智能管家SDK [1]前言: 今天给大家推荐个好用的开源框架:WisdomKeyboardKing,方面iOS日常开发,优点和功能请 ...
 - iOS  swift项目IM实现,从长连接到数据流解析分析之Socket
		
iOS swift项目IM实现,从长连接到底层数据解析分析之Socket 一:项目简介: 去年开始接手了一个国企移动项目,项目的需求是实现IM即时通讯功能. * 一期版本功能包括了: ...
 
随机推荐
- 【数论】【枚举约数】【欧拉函数】bzoj2705 [SDOI2012]Longge的问题
			
∵∑gcd(i, N)(1<=i <=N) =k1*s(f1)+k2*s(k2)+...+km*s(km) {ki是N的约数,s(ki)是满足gcd(x,N)=ki(1<=x< ...
 - lapis使用
			
lapis: 安装 http://leafo.net/lapis/ 官网安装方式依赖lua-cjson,但是已经安装了openresty的可能会报错. 解决方法,使用下面issue中的luarocks ...
 - 5.2类集(java学习笔记)Map,Set接口
			
一.Map接口 Map接口中存储数据是通过key->value的方式成对存储的,可以通过key找到value. 二.Map接口常用子类 1.HashMap HashMap是无序存放的,key不允 ...
 - Android修改状态栏颜色全方位教程
			
关键字:状态栏着色 透明状态栏 沉浸式 白底黑字 Github Demo:https://github.com/imflyn/Eyes 参考文章: Android-transulcent-status ...
 - centos7 安装nginx与配置
			
第一步安装 使用Yum安装是推荐的方式,整体的流程非常的简单,也不容易出错,如果不需要什么特殊配置,建议使用Yum尽进行安装. 第一种安装方式,通过添加epel源 yum install epel-r ...
 - webpack配置:less/sass文件打包和分离、自动处理css前缀、消除未使用的css及完整的webpack.config.js文件
			
一.less文件打包和分离 1.要使用less,首先使用npm安装less服务:还需要安装Less-loader用来打包使用. npm install less --save-dev npm inst ...
 - 解读Spark Streaming RDD的全生命周期
			
本节主要内容: 一.DStream与RDD关系的彻底的研究 二.StreamingRDD的生成彻底研究 Spark Streaming RDD思考三个关键的问题: RDD本身是基本对象,根据一定时间定 ...
 - 安装SpringExt以查看schema文件
			
安装SpringExt以查看schema文件 学习了:https://blog.csdn.net/ltianchao/article/details/43565167 spring ext啊 mvn ...
 - rails delegate机制
			
Delegate是一种应用composite来代替extend的机制,可以有效地降低代码的耦合性. Rails 2.2增加了delegate方法,可以十分方便地实现delegate机制. 01.def ...
 - TCP和UDP比較
			
一.TCP/IP协议 TCP/IP协议,你一定常常听说吧,当中TCP(Transmission Control Protocol)称为传输控制协议,IP(Internet Protocol)称为因特网 ...