QMUIEmotionInputManager

@interface QMUIEmotionInputManager : NSObject

提供一个常见的通用表情面板,能为绑定的UITextFieldUITextView提供表情的相关功能,包括点击表情输入对应的表情名字、点击删除按钮删除表情。 使用方式:

  1. 使用 init 方法初始化。
  2. 通过 boundTextFieldboundTextView 关联一个输入框,建议这些输入框使用 QMUITextFieldQMUITextView,原因看下面的 warning。
  3. 将所有表情通过 self.emotionView.emotions 设置进去,注意这个数组里的所有 QMUIEmotiondisplayName 都应该使用左右标识符包裹起来(例如中括号“[]”),并且所有表情的左右标识符都应该保持一致。
  4. self.emotionView add 到界面上即可。

Warning

一个QMUIEmotionInputManager无法同时绑定boundTextFieldboundTextView,在两者都绑定的情况下,优先使用boundTextField

Warning

由于QMUIEmotionInputManager里面多个地方会调用boundTextView.text,而setText:并不会触发UITextViewDelegatetextViewDidChange:UITextViewTextDidChangeNotification,以及 UITextFieldUIControlEventEditingChanged 事件,从而在刷新表情面板里的发送按钮的enabled状态时可能不及时,所以推荐使用 QMUITextView 代替 UITextView、用 QMUITextField 代替 UITextField,并确保它们的shouldResponseToProgrammaticallyTextChanges属性是 YES(默认即为 YES)。

Warning

由于表情的插入、删除都会受当前输入框的光标所在位置的影响,所以请在适当的时机更新selectedRangeForBoundTextInput的值,具体情况请查看该属性的注释。
  • 要绑定的 UITextField

    Declaration

    Objective-C

    @property (nonatomic, weak) UITextField *boundTextField;

    Swift

    weak var boundTextField: UITextField! { get set }
  • 要绑定的 UITextView

    Declaration

    Objective-C

    @property (nonatomic, weak) UITextView *boundTextView;

    Swift

    weak var boundTextView: UITextView! { get set }
  • selectedRangeForBoundTextInput决定了表情将会被插入(删除)的位置,因此使用控件的时候需要及时更新它。

    通常用到的更新时机包括:

    • 降下键盘显示表情面板之前(调用resignFirstResponder、endEditing:之前)
    • textViewDidChangeSelection:回调里
    • 输入框里的文字发生变化时,例如点了发送按钮后输入框文字会被清空,此时要重置selectedRangeForBoundTextInput为0

    Declaration

    Objective-C

    @property (nonatomic) NSRange selectedRangeForBoundTextInput;

    Swift

    var selectedRangeForBoundTextInput: NSRange { get set }
  • 表情面板,已被设置了默认的didSelectEmotionBlockdidSelectDeleteButtonBlock,在QMUIEmotionInputManager初始化完后,即可将emotionView添加到界面上。

    Declaration

    Objective-C

    @property (nonatomic, strong, readonly) QMUIEmotionView *emotionView;

    Swift

    var emotionView: QMUIEmotionView! { get }
  • 将当前光标所在位置的表情删除,在调用前请注意更新selectedRangeForBoundTextInput

    Declaration

    Objective-C

    - (BOOL)deleteEmotionDisplayNameAtCurrentSelectedRangeForce:(BOOL)forceDelete;

    Swift

    func deleteEmotionDisplayName(atCurrentSelectedRangeForce forceDelete: Bool) -> Bool

    Parameters

    forceDelete

    当没有删除掉表情的情况下(可能光标前面并不是一个表情字符),要不要强制删掉光标前的字符。YES表示强制删掉,NO表示不删,交给系统键盘处理

    Return Value

    表示是否成功删除了文字(如果并不是删除表情,而是删除普通字符,也是返回YES)

    • UITextViewDelegatetextView:shouldChangeTextInRange:replacementText: 或者 QMUITextFieldDelegatetextField:shouldChangeTextInRange:replacementText: 方法里调用,根据返回值来决定是否应该调用 deleteEmotionDisplayNameAtCurrentSelectedRangeForce:

    Declaration

    Objective-C

    - (BOOL)shouldTakeOverControlDeleteKeyWithChangeTextInRange:(NSRange)range
                                                replacementText:(NSString *)text;

    Swift

    func shouldTakeOverControlDeleteKeyWithChangeText(in range: NSRange, replacementText text: String!) -> Bool

    Parameters

    range

    要发生变化的文字所在的range

    text

    要被替换为的文字

    Return Value

    是否会接管键盘的删除按钮事件,YES 表示接管,可调用 deleteEmotionDisplayNameAtCurrentSelectedRangeForce: 方法,NO 表示不可接管,应该使用系统自身的删除事件响应。