美文网首页iOS分享世界MG的分类和继承
MG--如何设计一个带注释的文本框

MG--如何设计一个带注释的文本框

作者: Mg明明就是你 | 来源:发表于2017-05-30 12:09 被阅读108次

88.gif
77.gif
//  MGTextField.swift
//  MGLoginView
//  Created by ming.com on 2017/5/27.
//  Copyright © 2017年 i-Techsys. All rights reserved.

import UIKit

class MGTextField: UIView {
    // MARK: - 私有接口属性
    // 占位注释
    fileprivate var placeholderLabel: UILabel!
    // 线
    fileprivate var lineView: UIView!
    // 填充线
    fileprivate var lineLayer: CALayer!
    fileprivate let lineHeight: CGFloat = 1
    // 移动一次
    fileprivate var isMoved: Bool = false

    // MARK: - 公开接口属性
    // placeholder默认移动距离
    var xPadding: CGFloat = 6 // x
    var heightSpaceing: CGFloat = 3 // y
    // 文本框(提供给外界,设置键盘灯限制)
    fileprivate var textField: UITextField!

    //注释普通状态下颜色
    var placeholderNormalColor: UIColor! = UIColor.darkGray
    //注释选中状态下颜色
    var placeholderSelectColor: UIColor! = UIColor.black
    // 光标颜色
    var cusTintColor: UIColor! {
        didSet {
            textField.tintColor = cusTintColor
        }
    }
    var placeholderSring: String! {
        didSet {
            placeholderLabel.text = placeholderSring
        }
    }
    
    
    // MARK: - 系统初始化方法
    override init(frame: CGRect) {
        super.init(frame: frame)
        textField = TextField(frame: CGRect.zero)
        textField.borderStyle = .none
        textField.font = UIFont.systemFont(ofSize: CGFloat(15.0))
        textField.textColor = UIColor.white
        textField.tintColor = UIColor.white
        addSubview(textField)
        
        placeholderLabel = UILabel(frame: CGRect.zero)
        placeholderLabel.font = UIFont.systemFont(ofSize: CGFloat(13.0))
        placeholderLabel.textColor = UIColor.lightGray
        addSubview(placeholderLabel)
        
        lineView = UIView(frame: CGRect.zero)
        lineView.backgroundColor = UIColor.lightGray
        addSubview(lineView)
        
        lineLayer = CALayer()
        lineLayer.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(0), height: CGFloat(lineHeight))
        lineLayer.anchorPoint = CGPoint(x: CGFloat(0), y: CGFloat(0.5))
        lineLayer.backgroundColor = UIColor.white.cgColor
        lineView.layer.addSublayer(lineLayer)
        
        NotificationCenter.default.addObserver(self, selector: #selector(textFieldChange(_:)), name: NSNotification.Name.UITextFieldTextDidChange, object: textField)
        NotificationCenter.default.addObserver(self, selector: #selector(textFieldBeginEditing(_:)), name: NSNotification.Name.UITextFieldTextDidBeginEditing, object: textField)
        NotificationCenter.default.addObserver(self, selector: #selector(textFieldEndEditing(_:)), name: NSNotification.Name.UITextFieldTextDidEndEditing, object: textField)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        textField.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height-lineHeight )
        placeholderLabel.frame = CGRect(x: 10, y: 0, width: self.frame.width, height: self.frame.height-lineHeight )
        lineView.frame = CGRect(x: 0, y: self.frame.height-lineHeight, width: self.frame.width, height: lineHeight )
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}


extension MGTextField {
    /// 开始编辑
    @objc fileprivate func textFieldBeginEditing(_ noti: Notification)  {
        placeholderLabel.textColor = self.placeholderSelectColor
        UIView.animate(withDuration: 0.15) {
            self.lineLayer.bounds = CGRect(x: 0, y: 0, width: self.frame.width, height: self.lineHeight)
        }
    }
    
    
    /// 结束编辑
    @objc fileprivate func textFieldEndEditing(_ noti: Notification)  {
        placeholderLabel.textColor = self.placeholderNormalColor
        UIView.animate(withDuration: 0.15) {
            self.lineLayer.bounds = CGRect(x: 0, y: 0, width: 0, height: self.lineHeight)
        }
    }
    
    /// 文本框改变的时候调用
    ///
    /// - Parameter noti:
    @objc fileprivate func textFieldChange(_ noti: Notification) {
        changeFrameOfPlaceholder()
    }
    
    /// 改变占位文字的位置
    fileprivate func changeFrameOfPlaceholder() {
        let y = placeholderLabel.center.y;
        let x = placeholderLabel.center.x;
        
        if(textField.text?.characters.count != 0 && !isMoved){
            self.placeholderLabelMoveAnimation(x: x, y: y)
        }else if(textField.text?.characters.count == 0 && isMoved){
            self.placeholderLabelMoveBackAnimation(x: x, y: y)
        }
    }
    
    
    /// 文本框有文字时占位字符移动
    ///
    /// - Parameters:
    ///   - x: 占位Label的中心点x
    ///   - y: 占位Label的中心点y
    fileprivate func placeholderLabelMoveAnimation(x: CGFloat, y: CGFloat) {
        var moveX = x
        var moveY = y
        placeholderLabel.font = UIFont.systemFont(ofSize: 12)
        placeholderLabel.textColor = placeholderSelectColor
        
        UIView.animate(withDuration: 0.15, animations: {() -> Void in
            moveY -= self.placeholderLabel.frame.size.height / 2 + self.heightSpaceing
            moveX -= self.xPadding
            self.placeholderLabel.center = CGPoint(x: moveX, y: moveY)
            self.placeholderLabel.alpha = 1
            self.isMoved = true
        })
    }
    
    /// 文本框被清空时占位字符回到原始位置
    ///
    /// - Parameters:
    ///   - x: 占位Label的中心点x
    ///   - y: 占位Label的中心点y
    fileprivate func placeholderLabelMoveBackAnimation(x: CGFloat, y: CGFloat) {
        var moveX = x
        var moveY = y
        placeholderLabel.font = UIFont.systemFont(ofSize: 15)
        placeholderLabel.textColor = placeholderNormalColor
        
        UIView.animate(withDuration: 0.15, animations: {() -> Void in
            moveY += self.placeholderLabel.frame.size.height / 2 + self.heightSpaceing
            moveX += self.xPadding
            self.placeholderLabel.center = CGPoint(x: moveX, y: moveY)
            self.placeholderLabel.alpha = 1
            self.isMoved = false
        })
    }
}


// MARK: - 主要是设置光标位置
class TextField: UITextField {
    override func textRect(forBounds bounds: CGRect) -> CGRect {
        let inset = CGRect(x: bounds.origin.x + 10, y: bounds.origin.y, width: bounds.size.width - 25, height: bounds.size.height)
        //更好理解些
        return inset
    }
    
    // 重写来编辑区域,可以改变光标起始位置,以及光标最右到什么地方,placeHolder的位置也会改变
    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return CGRect(x: bounds.origin.x + 10, y: bounds.origin.y, width: bounds.size.width - 25, height: bounds.size.height)
    }
}


  • 轻轻点击,关注我简书

轻轻点击,关注我简书

轻轻点击,关注我微博

浏览我的GitHub


  • 扫一扫,关注我

扫一扫,关注我.jpg

相关文章

网友评论

    本文标题:MG--如何设计一个带注释的文本框

    本文链接:https://www.haomeiwen.com/subject/gbeqfxtx.html