zoukankan      html  css  js  c++  java
  • 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):

    1. 限制输入的字符(数字,字母,数字+字母,email等)
    2. 提供一个可以监听textField实时改变的方法,不需要自己去写观察者
    3. 限制输入文字的最大长度
    4. 限制textField距离leftPading rightPading
    5. 更方便快捷的设置leftView rightView
    6. 设置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,  bounds.size.width, height: bounds.size.height)
                return super.placeholderRect(forBounds: rect)
            }
            return super.placeholderRect(forBounds: bounds)
        }
        
    }
    
    
  • 相关阅读:
    GPRS DTU通信的本质及调试经验
    winform 控件处在中间位置
    winform 多panel编辑
    Winform 控件多闪屏问题解决方法
    int 转换 byte[] 或 byte[] 转换 int
    java 多线程(一)
    postgresql 一些操作备忘
    idea eclipse web项目
    redis 入门
    idea 版本控制
  • 原文地址:https://www.cnblogs.com/qqcc1388/p/9910778.html
Copyright © 2011-2022 走看看