美文网首页
Swift inputView自定义输入框 + 表情键盘

Swift inputView自定义输入框 + 表情键盘

作者: 吃货_X | 来源:发表于2020-12-11 11:51 被阅读0次

部分代码需要更改(有提示,自行处理)

import UIKit
import YYKit

let spaceLeft       :CGFloat = 15
let spaceTop        :CGFloat = 10
let spaceDouble     :CGFloat = 2 * spaceTop
let textViewHeight  :CGFloat = 38
var textViewWidth   :CGFloat {get{ return UIScreen.main.bounds.width - 2 * spaceLeft }}
let MTotleHeight    :CGFloat = spaceDouble + textViewHeight
var MaineHeight     :CGFloat {get{ return UIScreen.main.bounds.height }}
var MaineWidth      :CGFloat {get{ return UIScreen.main.bounds.width }}


enum MomentsInputType: Int {
    case main
    case detail
}

public enum keyboardListen {
    ///正常键盘关闭
    case close
    ///输入@监听
    case listen(NSAttributedString?,NSRange?)
    ///发送消息
    case send(String)
}

class MomentComentInputView: UIView {   
    var isShow:Bool = false
    var isAdd:Bool = false
    /** 字符长度限制:默认200 */
    var maxStringCount:Int = 200
    /** 最大高度 */
    var maxInputHeight:CGFloat = 112
    var listening:((keyboardListen) -> ())
    /** 状态栏高度 */
    var StatusBarHeight:CGFloat{
        get{
            if #available(iOS 13.0, *){
                return UIApplication.shared.windows.first?.windowScene?.statusBarManager?.statusBarFrame.height ?? 20
            } else {
                return UIApplication.shared.statusBarFrame.size.height
            }
        }
    }
    
    /** 导航高度 */
    var navHeight:CGFloat{
        get {
            switch type {
            case .main:
                return 0
            default:
                return StatusBarHeight + 44 - 5
            }
        }
    }
    
    var type: MomentsInputType
    
    init(frame: CGRect,type: MomentsInputType,listening:@escaping ((keyboardListen) -> ())) {
        self.type = type
        self.listening = listening
        super.init(frame: frame)
        configSubviews()
    }
    private func configSubviews() {
        self.backgroundColor = .white
        line.frame = CGRect(x: 0, y: 0, width: MaineWidth, height: 0.5)
        self.addSubview(textView)
        self.addSubview(emojiButton)
        self.addSubview(line)
        
        NotificationCenter.default.addObserver(self,selector: #selector(keyBoardWillShow(_ :)),name: UIResponder.keyboardWillShowNotification,object: nil)
        
        NotificationCenter.default.addObserver(self,selector: #selector(keyBoardWillHide(_ :)),name: UIResponder.keyboardWillHideNotification,object: nil)
        
        NotificationCenter.default.addObserver(self,selector: #selector(keyBoardDidHide(_ :)),name: UIResponder.keyboardDidHideNotification,object: nil)
        
        textView.addObserver(self, forKeyPath: "contentSize", options: [.new], context: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    ///调起键盘输入框
    public class func showkeybord(type: UIKeyboardType,attributedValue:(NSMutableAttributedString?,NSRange?)? = nil,placeHolder:String,_ maxStringCount:Int = 400,listening:@escaping ((keyboardListen) -> ())) {
        var superView:UIView? = UIApplication.shared.keyWindow?.rootViewController?.view
        var inPutView : MomentComentInputView
        if let view:MomentComentInputView = superView?.viewWithTag(10011) as? MomentComentInputView {
            view.textView.endEditing(true)
            inPutView = view
        } else {
            inPutView =  MomentComentInputView.init(frame: CGRect(x: 0, y: MaineHeight, width: MaineWidth, height: 0),  type: .main, listening: listening)
            inPutView.tag = 10011
        }
        
        inPutView.maxStringCount = maxStringCount
        inPutView.textView.keyboardType = type
        inPutView.textView.placeholderText = placeHolder
        inPutView.textView.becomeFirstResponder()
        if let att = attributedValue,let str = att.0  {
            inPutView.textView.setAttributedTextButNoSelected(str)
            var selectedRange = NSRange(location: str.string.count, length: 0)
            if let range = att.1 {
                selectedRange = range
            }
            inPutView.textView.selectedRange = selectedRange
        }
        // 顶部黑色背景
        var backView:UIButton
        if let button:UIButton = superView?.viewWithTag(10012) as? UIButton {
            button.alpha = 0
            backView = button
        } else {
            backView = UIButton.init()
            backView.tag = 10012
        }
        
        backView.backgroundColor = UIColor.rgbColor(0, 0, 0, 0.4)
        backView.addTarget(inPutView, action: #selector(closeKeybord(_:)), for: .touchUpInside)
        backView.frame = CGRect(x: 0, y: 0, width: MaineWidth, height: MaineHeight)
        backView.alpha = 0
        
        UIApplication.shared.keyWindow?.endEditing(true)
        superView?.addSubview(backView)
        superView?.addSubview(inPutView)
        UIView.animate(withDuration: 0.25) {
            backView.alpha = 1
        }
    }
    
    
    //MARK:键盘通知相关操作
    @objc func keyBoardWillShow(_ notification:Notification){
        let user_info = notification.userInfo
        let keyboardRect = (user_info?[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        let animationTime:TimeInterval = user_info?[UIResponder.keyboardAnimationDurationUserInfoKey] as! TimeInterval
        let y = keyboardRect.origin.y
        let top =  y - (self.isShow ? self.mj_h : MTotleHeight)
        MomentsNotification.postNotification(.showKeyboardNotifi, object: nil, userInfo: ["top": top, "dealy": CGFloat(animationTime)])
        if isShow {
            self.mj_y = top;
        } else {
             //self.currentLayout.safeInsets(处理x系列横屏左右边距,自行解决)
            UIView.animate(withDuration: animationTime) {
                self.frame = CGRect(x: 0, y: top, width: MaineWidth, height: MTotleHeight)
                self.textView.frame = CGRect(x:self.currentLayout.safeInsets.left + spaceLeft, y: spaceTop, width: textViewWidth - self.currentLayout.safeInsets.left - self.ADAPTATION_WIDTH414(50), height: textViewHeight)
                self.emojiButton.frame = CGRect(x: self.textView.right + self.ADAPTATION_WIDTH414(6), y:MTotleHeight - spaceTop - 4 - self.ADAPTATION_WIDTH414(35)  , width: self.ADAPTATION_WIDTH414(50), height: self.ADAPTATION_WIDTH414(40))
            }
            self.isShow = true
        }
    }
    
    func ADAPTATION_WIDTH414( _ value:CGFloat) -> CGFloat {
        return (MaineWidth > 414 ? 414 : MaineWidth) * value / 414.0
    }
    
    @objc func keyBoardWillHide(_ notification:Notification){
        var superView:UIView? superView = UIApplication.shared.keyWindow?.rootViewController?.view
        UIApplication.shared.keyWindow?.endEditing(true)
        let user_info = notification.userInfo
        let animationTime:TimeInterval = user_info?[UIResponder.keyboardAnimationDurationUserInfoKey] as! TimeInterval
         //self.currentLayout.safeInsets(处理x系列横屏左右边距,自行解决)
        UIView.animate(withDuration: animationTime) {
            if let button:UIButton = superView?.viewWithTag(10012) as? UIButton {
                button.alpha = 0
            }
            self.textView.text = nil
            self.textView.frame = CGRect(x: self.currentLayout.safeInsets.left + spaceLeft, y: spaceTop, width: textViewWidth - self.currentLayout.safeInsets.left - self.ADAPTATION_WIDTH414(50), height: 0)
            self.emojiButton.frame = CGRect(x: self.textView.right + self.ADAPTATION_WIDTH414(6), y:MTotleHeight - spaceTop - 4 - self.ADAPTATION_WIDTH414(35)  , width: self.ADAPTATION_WIDTH414(50), height: self.ADAPTATION_WIDTH414(40))
            self.frame = CGRect(x: 0, y: MTotleHeight + MaineHeight, width:MaineWidth , height: 0)
        }
    }
    
    @objc func keyBoardDidHide(_ notification:Notification){
        var superView:UIView? = UIApplication.shared.keyWindow?.rootViewController?.view
            UIApplication.shared.keyWindow?.endEditing(true)
        if let view:MomentComentInputView = superView?.viewWithTag(10011) as? MomentComentInputView {
            view.textView.endEditing(true)
            view.removeFromSuperview()
        }
        if let button:UIButton = superView?.viewWithTag(10012) as? UIButton {
            button.removeFromSuperview()
        }
    }
    
    @objc func closeKeybord(_ sender:UIButton) {
        listening(.close)
        UIApplication.shared.keyWindow?.endEditing(true)    
    }
    
    private func hiddenTextView(){
        self.textView.isHidden = true
    }
    
    @objc private func setEmojiInputview(_ sender:UIButton){
        sender.isSelected = !sender.isSelected
        tap.isEnabled = sender.isSelected
        if sender.isSelected {
            self.emojiView.frame = CGRect(x: 0, y: 0, width:MaineWidth, height: 270)
            self.textView.inputView = self.emojiView
            textView.inputAccessoryView = UIView.init(frame: CGRect(x: 0, y: 0, width: MaineWidth, height: 0.00001))
        } else {
            self.textView.inputAccessoryView = UIView()
            self.textView.inputView = nil
        }
        
        self.textView.reloadInputViews()
    }
    
    public func textViewTap(_ tap:UIGestureRecognizer){
        if self.emojiButton.isSelected == false {
            return
        }
        let touchPoint:CGPoint = tap.location(in: self)
        if self.textView.frame.contains(touchPoint) == false {
            return
        }
        self.emojiButton.isSelected = false
        self.textView.inputAccessoryView = UIView()
        self.textView.inputView = nil
        self.textView.reloadInputViews()
        tap.isEnabled = emojiButton.isSelected
    }
    
    @objc public func yyTextViewTap(_ tap:UITapGestureRecognizer) {
        if emojiButton.isSelected == false {
            return
        }
        emojiButton.isSelected = false
        textView.inputAccessoryView = UIView()
        textView.inputView = nil
        textView.reloadInputViews()
        tap.isEnabled = emojiButton.isSelected
        let touchPoint:CGPoint = tap.location(in: textView)
        let range:NSRange = (textView.characterRange(at: CGPoint(x: touchPoint.x, y:touchPoint.y - 90 )) as! YYTextRange).asRange()
        textView.selectedRange = NSRange(location: range.location, length: 0)
        if textView.text.count == 1 && textView.text != "@" {
            textView.setAttributedTextButNoSelected(getNeedheighliht(content: textView.text))
        }
    }
    
    //MARK: - 高亮昵称
    func findAllAt(content: String) -> [NSTextCheckingResult]{
        var resultArr: [NSTextCheckingResult] = []
        //@[\\u4e00-\\u9fa5\\w\\-\\_]+\\00 正则
        let regular = try? NSRegularExpression(pattern: "@.*?\\00", options: .caseInsensitive)
        if let regux = regular {
            resultArr = regux.matches(in: content, options: .reportProgress, range: NSMakeRange(0, content.count))
        }
        return resultArr
    }
    func getNeedheighliht(content: String) -> NSMutableAttributedString {
        let nsStr = content as NSString
        let att = NSMutableAttributedString(string: content)
        att.addAttribute(.font, value: Font.regular(15), range: NSMakeRange(0, nsStr.length))
        att.addAttribute(.foregroundColor, value: UIColor(rgb: 0x333333), range: NSMakeRange(0, nsStr.length))
        
        let regular = try? NSRegularExpression(pattern: "@.*?\\00", options: .caseInsensitive)
        if let regux = regular {
            // regux.enumerateMatches(in: content, options: .reportProgress, range: NSMakeRange(0, content.count)) { (result, flags, stop) in }
            let resultArr = regux.matches(in: content, options: .reportProgress, range: NSMakeRange(0, nsStr.length))
            for result in resultArr {
                att.setTextHighlight(result.range, color: UIColor(rgb: 0x09A4C9), backgroundColor: nil, tapAction: nameClicked())
            }
            return att
        } else { return att}
    }
    
    //TODO: 昵称点击
    func nameClicked() -> (YYTextAction) {
        
        let block: YYTextAction = { (v1: UIView, v2: NSAttributedString, v3: NSRange, v4: CGRect) in
            print("---- @好友点击", v2.string)
        }
        return block
    }
    
    
    //MARK: - 输入框监听
    override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "contentSize" {
            let view:YYTextView = object as! YYTextView
            var height = view.contentSize.height
            if height > maxInputHeight {
                height = maxInputHeight;
            }
            if height < textViewHeight {
                height = textViewHeight
            }
            var textViewFrame = self.textView.frame;
            textViewFrame.size.height = height;
            self.textView.frame = textViewFrame;
            updateSelfOfTextViewSize()
        }
        
    }
    
    private func updateSelfOfTextViewSize() {
        if textView.height > maxInputHeight {
            return
        }
        UIView.animate(withDuration: 0.25) {
            var rect = self.frame
            rect.size.height = self.textView.frame.size.height + spaceDouble
            let sourceY = rect.origin.y
            let disY = rect.size.height - self.frame.size.height
            rect.origin.y = sourceY - disY
            self.emojiButton.mj_y = rect.height - spaceTop - 4 - self.ADAPTATION_WIDTH414(35)
            self.frame = rect
        }
    }
    
    //MARK: - Getter/Setter
    lazy var line:UILabel = {
        let line = UILabel.init()
        line.backgroundColor = UIColor.rgbColor(211, 211, 211)
        return line
    }()
    
    lazy var textView:YYTextView = {
        let textView = YYTextView.init()
        textView.clipsToBounds = true
        textView.layer.borderWidth = 1.0
        textView.layer.borderColor = UIColor(rgb: 0xD8D8D8).cgColor
        textView.layer.cornerRadius = 19
        textView.returnKeyType = .send
        textView.font = Font.regular(15)
        textView.keyboardType = .default
        textView.textContainerInset = UIEdgeInsets.init(top: 9, left: 16, bottom: 9, right: 16)
        textView.delegate = self
        textView.backgroundColor = .clear
        textView.placeholderFont = Font.regular(15)
        textView.placeholderTextColor = UIColor(rgb: 0xBCBCBC)
        textView.inputAccessoryView = UIView()
        textView.showsVerticalScrollIndicator = false
        textView.showsHorizontalScrollIndicator = false
        textView.addGestureRecognizer(self.tap)
        let paraph = NSMutableParagraphStyle()
        paraph.lineSpacing = 5
        let attributed:[String:Any] = [NSAttributedString.Key.font.rawValue:Font.regular(15), NSAttributedString.Key.paragraphStyle.rawValue:paraph]
        textView.typingAttributes = attributed
        return textView
    }()
    
    lazy var tap:UITapGestureRecognizer = {
        let tap = UITapGestureRecognizer.init(target: self, action: #selector(yyTextViewTap(_:)))
        tap.isEnabled = false
        return tap
    }()
    
    
    lazy var emojiButton:UIButton = {
        let button = UIButton.init(type: .custom)
        let emojiImage = UIImage(bundleImageName: "Moment/Moment_Face_emoji")
        button.setImage(emojiImage, for: .normal)
        let keyBordImage = UIImage(bundleImageName: "Chat/Input/Text/AccessoryIconKeyboard")
        button.setImage(keyBordImage, for: .selected)
        button.addTarget(self, action: #selector(setEmojiInputview(_:)), for: .touchUpInside)
        return button
    }()
    
    private lazy var emojiView: MomentSEmojiView = {
        let view = MomentSEmojiView(frame: CGRect(x: 0, y: 0, width:MaineWidth, height: 270))
        view.delegate = self
        return view
    }()
    
    deinit {
        NotificationCenter.default.removeObserver(self)
        self.textView.removeObserver(self, forKeyPath: "contentSize")
    }
}

extension MomentComentInputView:YYTextViewDelegate {
    
    func textView(_ textView: YYTextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        
        if text == "\n" {
            if textView.text.count == 0 {
                return false
            }
            if  textView.text.count > 0 {
                listening(.send(textView.text))
                textView.endEditing(true)
                return false
            }
        }
        
        if (text.count + textView.text.count) > maxStringCount || range.location > maxStringCount {
            let notice:String = "超出最大字数提示"
            MomentsToast.show(notice, in: self.superview!)
            return false
        }
        
        if text == "@" {
            listening(.listen(textView.attributedText,textView.selectedRange))
            textView.endEditing(true)
            return false
        }
        
        if text == "" {
            textView.selectedRange = NSMakeRange(range.location, 0)
            let array = findAllAt(content: textView.text)
            var inAt = false
            var index = range.location
            for match in array {
                let newRange = NSMakeRange(match.range.location + 1, match.range.length - 1)
                if NSLocationInRange(range.location, newRange) {
                    inAt = true
                    index = match.range.location
                    let newStr = textView.text! as NSString
                    let new = newStr.replacingCharacters(in: match.range, with: "")
                    textView.setAttributedTextButNoSelected(self.getNeedheighliht(content: new))
                    break
                }
            }
            if inAt {
                textView.selectedRange = NSMakeRange(index, 0)
                return false
            }
        }
        
        return true
    }
    
    func textViewDidChange(_ textView: YYTextView) {
        
    }
    public func textViewDidChangeSelection(_ textView: YYTextView) {
        let range  = textView.selectedRange
        if range.length > 0 {
            return
        }
        let arr = findAllAt(content: textView.text)
        for match in arr {
            let newRange = NSMakeRange(match.range.location + 1, match.range.length - 1)
            if NSLocationInRange(range.location, newRange) {
                textView.selectedRange = NSMakeRange(match.range.location + match.range.length, 0)
                // print("---- 昵称范围:",textView.selectedRange.location)
                break
            } else {
                textView.setAttributedTextButNoSelected(self.getNeedheighliht(content: textView.text))
            }
        }
        if textView.text.count == 1 && textView.text != "@" {
            textView.setAttributedTextButNoSelected(self.getNeedheighliht(content: textView.text))
        }
    }
}

extension MomentComentInputView:MomentsViewBaseCompatible {
    func updateThemeAndStrings(_ presentationData: PresentationData) {
        self.backgroundColor = self.presentationData.theme.list.itemBlocksBackgroundColor
    }
    
    func updateLayout(_ layout: ContainerViewLayout) {
        if layout.size.width != self.currentLayout.size.width {
            setFrame(with: layout)
        }
    }
    
    func setFrame(with layout: ContainerViewLayout) {
        
    }
    
    
}

extension MomentComentInputView:MomentsEmojiViewDelegate {
    func appendEmoji(_ emojiStr: String){
        self.textView.insertText(emojiStr)
        
        // 常有表情存储
        let key = "commonfaces"
        if var commons = UserDefaults.standard.object(forKey: key) as? Array<String> {
            if commons.contains(emojiStr) {
                for (index,value) in commons.enumerated() {
                    if value == emojiStr {
                        commons.remove(at: index)
                        break
                    }
                }
            }
            commons.insert(emojiStr, at: 0)
            // 最多存储10个
            if commons.count > 10 {
                commons.removeLast()
            }
            UserDefaults.standard.set(commons, forKey: key)
            UserDefaults.standard.synchronize()
        } else {
            UserDefaults.standard.set([emojiStr], forKey: key)
            UserDefaults.standard.synchronize()
        }
    }
    
    func deleteEmoji(){
        self.textView.deleteBackward()
    }
    
    func sendEmojiStr(){
        if textView.text.count > 0 {
            listening(.send(textView.text))
            textView.endEditing(true)
        }
    }
}

表情键盘

import Foundation
import UIKit

@objc protocol MomentsEmojiViewDelegate {
    func appendEmoji(_ emojiStr: String) // 添加
    func deleteEmoji() // 删除最后一个字符
    func sendEmojiStr() // 发送
}

class MomentSEmojiView: UIView {
    
    let emojis: [String] = ["😀","😬","😁","😂","😃","😄","😅","😆","😇","😉","😊","🙂","🙃","☺️","😋","😌","😍","😘","😗","😙","😚","😜","😝","😛","🤑","🤓","😎","🤗","😏","😶","😐","😑","😒","🙄","🤔","😳","😞","😟","😠","😡","😔","😕","🙁","☹️","😣","😖","😫","😩","😤","😮","😱","😨","😰","😯","😦","😧","😢","😥","😪","😓","😭","😵","😲","🤐","😷","🤒","🤕","😴","💤","💩","😈","👿","👹","👺","💀","👻","👽","🤖","😺","😸","😹","😻","😼","😽","🙀","😿","😾","🙌","👏","👋","👍","👎","👊","✊","✌","👌","✋","👐","💪","🙏","☝","👆","👇","👈","👉","🖕","🖐","🤘","🖖","✍","💅","👄","👅","👂","👃","👁","👀","👶","👦","👧","👨","👩","👱","👴","👵","👲","👳","👮","👷","💂","🕵","🎅","👼","👸","👰","🚶","🏃","💃","👫","👪","👬","👭","💏","💑","👯","🙆","🙅","💁","🙋","💆","💇","💅","👰","🙎","🙍","🙇","🎀","🌂","💄","💛","💙","💜","💚","❤️","💔","💗","💓","💕","💖","💞","💘","💌","💋","💍","💎","👤","👥","💬","👣","💭","","",""]
    var datas:Array<Dictionary<String, Any>> = []
    
    override var safeAreaInsets: UIEdgeInsets {
        get {
            if #available(iOS 11.0, *) {
                var statusBarFrameHeight: CGFloat = 0.0
                if #available(iOS 13.0, *) {
                    statusBarFrameHeight = UIApplication.shared.windows.first?.windowScene?.statusBarManager?.statusBarFrame.size.height ?? 20
                } else {
                    statusBarFrameHeight = UIApplication.shared.statusBarFrame.size.height
                }
                if statusBarFrameHeight == 20.0 {
                    return UIEdgeInsets.zero
                }
                return UIApplication.shared.windows.first?.safeAreaInsets ?? UIEdgeInsets.zero
            } else {
                return UIEdgeInsets.zero
            }
        }
    }
    
    weak var delegate: MomentsEmojiViewDelegate?
    
    private var sendButton: UIButton?
    private var deleteButton: UIButton?
    private var backV:UIView?
    
    private lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout.init()
        layout.itemSize = CGSize(width: 32, height: 30)
        layout.minimumLineSpacing = 10
        layout.minimumInteritemSpacing = 5
        layout.scrollDirection = .vertical
        layout.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        // 设置分区头视图和尾视图宽高
        layout.headerReferenceSize = CGSize(width: MaineWidth, height: 30)
        //layout.footerReferenceSize = CGSize(width: 0, height: 0)
        let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
        cv.delegate = self
        cv.dataSource = self
        if #available(iOS 11.0, *) {
            cv.contentInsetAdjustmentBehavior = UIScrollView.ContentInsetAdjustmentBehavior.never
        }
        cv.showsVerticalScrollIndicator = false
        cv.showsHorizontalScrollIndicator = false
        cv.register(MomentsEmojiCollectionViewCell.self, forCellWithReuseIdentifier: "MomentsEmojiCollectionViewCell")
        cv.register(MomentsEmojiCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "MomentsEmojiCollectionReusableView")
        cv.backgroundColor = UIColor.white
        return cv
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        backgroundColor = UIColor.white
        
        addSubview(self.collectionView)
        collectionView.snp.makeConstraints {
            $0.top.right.left.equalToSuperview()
            $0.bottom.equalToSuperview().offset(-safeAreaInsets.bottom)
            //$0.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 0, bottom: -safeAreaInsets.bottom, right: 0))
        }

        let backView = UIView()
        backV = backView
        //backView.backgroundColor = UIColor.black
        addSubview(backView)
        
        let sBtn = UIButton(type: .custom)
        sBtn.setTitle("发送", for: .normal)
        sBtn.titleLabel?.font = UIFont.systemFont(ofSize: 13)
        sBtn.isUserInteractionEnabled = false
        sBtn.setTitleColor(UIColor.white, for: .normal)
        sBtn.backgroundColor = UIColor(rgb:0x268CFF)//UIColor(red: 38/255.0, green: 140/255.0, blue: 255.0/255.0, alpha: 0.6)
        sBtn.layer.cornerRadius = 4
        sBtn.addTarget(self, action: #selector(clickSendButton), for: .touchUpInside)
        sendButton = sBtn
        backView.addSubview(sBtn)
        
        let dBtn = UIButton(type: UIButton.ButtonType.custom)
        let bgImage = UIImage(bundleImageName: "Moment/icon_deleFace")?.precomposed()
        dBtn.setImage(bgImage, for: .normal)
        dBtn.backgroundColor = .white
        dBtn.addTarget(self, action: #selector(clickDeleteButton), for: .touchUpInside)
        deleteButton = dBtn
        backView.addSubview(dBtn)
        
        backView.snp.makeConstraints {
            $0.right.equalToSuperview().offset((UIDevice.current.model != "iPhone" ? 0 : 0))
            $0.bottom.equalTo(collectionView)
        }
        
        sBtn.snp.makeConstraints {
            $0.right.equalToSuperview().offset(-8)
            $0.bottom.equalToSuperview().offset(-4)
            $0.width.equalTo(50)
            $0.height.equalTo(30)
            $0.top.equalToSuperview().offset(12)
        }
        dBtn.snp.makeConstraints {
            $0.right.equalTo(sBtn.snp.left).offset(-8)
            $0.centerY.equalTo(sBtn)
            $0.width.height.equalTo(sBtn)
            $0.left.equalToSuperview().offset(8)
        }
        
        loadData()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 发送
    @objc private func clickSendButton() {
        delegate?.sendEmojiStr()
    }
    
    // 删除
    @objc private func clickDeleteButton() {
        delegate?.deleteEmoji()
    }
    
    public func textViewCurrentText(_ text: NSString) {
        if text.length > 0 {
            sendButton?.isUserInteractionEnabled = true
            sendButton?.backgroundColor = UIColor(rgb:0x268CFF) // UIColor(red: 38/255.0, green: 140/255.0, blue: 255.0/255.0, alpha: 1)
        } else {
            sendButton?.isUserInteractionEnabled = false
            sendButton?.backgroundColor = UIColor(rgb:0x268CFF,alpha: 0.6) // UIColor(red: 38/255.0, green: 140/255.0, blue: 255.0/255.0, alpha: 0.6)
        }
    }
    
    private func loadData() {
        if let commons = UserDefaults.standard.object(forKey: "commonfaces") as? Array<String> {
            if commons.count > 0 {
                let dic = ["title":"常用表情","items":commons] as [String : Any]
                datas.append(dic)
            }
        }
        datas.append(["title":"所有表情","items":emojis])
        collectionView.reloadData()
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        //处理点击发送无反应
        let touch = ((touches as NSSet).anyObject() as AnyObject)
        let touchPoint:CGPoint = touch.location(in:backV)
        if self.sendButton?.frame.contains(touchPoint) == true {
            delegate?.sendEmojiStr()
        }
    }
}

extension MomentSEmojiView: UICollectionViewDelegate, UICollectionViewDataSource {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        let dic = datas[section]["items"] as! Array<String>
        return dic.count
    }
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return datas.count
    }
    
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        if kind == UICollectionView.elementKindSectionHeader {
            let string = datas[indexPath.section]["title"] as! String
            let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "MomentsEmojiCollectionReusableView", for: indexPath) as! MomentsEmojiCollectionReusableView
            header.titleLabel.text = string
            return header
        }
        return UIView() as! UICollectionReusableView
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MomentsEmojiCollectionViewCell", for: indexPath) as! MomentsEmojiCollectionViewCell
        let strings = datas[indexPath.section]["items"] as! Array<String>
        cell.emojiLabel.text = strings[indexPath.row]
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let strings = datas[indexPath.section]["items"] as! Array<String>
        let string = strings[indexPath.row]
        if string != "" {
            delegate?.appendEmoji(string)
        }
    }
}


import UIKit

class MomentsEmojiCollectionReusableView: UICollectionReusableView {
    var titleLabel: UILabel!
        
    override init(frame:CGRect) {
        super.init(frame: frame)
        setupUI()
    }
        
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
        
    private func setupUI() {
        titleLabel = UILabel()
        titleLabel.font = UIFont.systemFont(ofSize: 13)
        titleLabel.textColor = UIColor.black
        
        self.addSubview(titleLabel)
        self.backgroundColor = UIColor.white
    }
        
    override func layoutSubviews() {
        super.layoutSubviews()
            
        //let frame: CGRect = self.bounds
        //let frameWidth: CGFloat = frame.size.width

        //self.titleLabel.frame = CGRect(x: 10, y:5 , width: frameWidth, height: frame.size.height - 10)
        titleLabel.snp.makeConstraints {
            $0.centerY.equalToSuperview().offset(5)
            $0.left.equalToSuperview().offset(10)
        }
    }
        
    override func awakeFromNib() {
        super.awakeFromNib()
    }
}


import UIKit
import Display//这儿的作用相当于:SnapKit

class MomentsEmojiCollectionViewCell: UICollectionViewCell {
    var imageView: UIImageView!
    var emojiLabel: UILabel!
    
    override init(frame:CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        emojiLabel = UILabel()
        emojiLabel?.font = Font.regular(15)
        emojiLabel?.textAlignment = .center
        self.addSubview(emojiLabel)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        //用SnapKit的功能或frame设置替代一样的
        self.emojiLabel.snp.makeConstraints {
            $0.edges.equalToSuperview()
        }
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }
}

相关文章

  • Swift inputView自定义输入框 + 表情键盘

    部分代码需要更改(有提示,自行处理) 表情键盘

  • 与键盘的那点事

    1.自定义键盘 ``` self.view.inputView: ``` 2.退出键盘 ``` 1> [self ...

  • Android自定义验证码输入框和键盘

    先上效果图: 自定义输入框: 输入框布局xml: 自定义键盘: 输入框监听键盘: 需要注意的坑:自定义keyboa...

  • iOS系统表情键盘

    UITextField和UITextView的inputView属性就是用来加入自定义键盘的,使用时赋值即可: 恢...

  • IOS自定义键盘

    效果图 自定义键盘的核心思想 设置UITextFiled 的InputView切换键盘的思路为重新设置UIText...

  • UIPickerView

    使用场景 通常在注册模块,通过自定义inputView来自定义键盘加一个UIDatePicker来实现日期的选择 ...

  • iOS自定义键盘

    对于有输入功能的控件,例如UITextField,可以给控件的inputView属性赋值,实现自定义键盘的功能 点...

  • 用EidtText发送Emoji表情需要注意的问题

    需要注意问题 EditText输入框里面的表情大小和键盘的Emoji表情大小一致 EditText输入框里面的表情...

  • 遇到的坑

    键盘通知导致UI异常现象描述:本地详情页的inputView输入框,做了很多的功能,由多个view组成,这时点击微...

  • 高仿支付宝密码输入框

    先上图 自定义键盘view 自定义EditText输入框 fragment anim dialog_in.xml...

网友评论

      本文标题:Swift inputView自定义输入框 + 表情键盘

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