消息输入控件完全自定义

更新时间:2016/01/26 访问次数:6521

消息输入控件完全自定义

聊天页面预置的消息输入控件——YWMessageInputView 提供颜色、图片素材配置以及插件扩展的定制能力,当定制能力不足以满足需求时,则可以使用完全自定义的输入控件。

要实现消息输入控件分为3部分工作:
1. 创建 UIView 子类并遵守 IYWMessageInputView 协议使之作为消息输入控件,控件内部可添加如 UITextView 类型的子视图作为文本输入控件,同时将协议中规定的 textselectedRange 属性关联至文本输入控件
2. 实现 IYWMessageInputView 协议中规定的 id<YWMessageInputViewDelegate> messageInputViewDelegate 属性用于引用委托对象,同时负责在适当时机回调委托对象。
3. 替换 YWConversationViewController 的消息输入控件

以下的内容中,将创建一个简单的消息输入控件 ,内部以 UITextView 子视图作为文本输入控件。
同时 Demo 的工程中附带了一个示例实现 SPMessageInputView 可作为辅助参考

创建自定义消息输入控件

只要遵守 IYWMessageInputView 协议,输入控件本身可以从 UIView 本身或其任何子类中派生而来:

@interface SPMessageInputView : UIView
<IYWMessageInputView>

@property (nonatomic, weak, readonly) UITextView *inputTextView;

@end

实现 IYWMessageInputView 协议

协议中定义了3个必须实现的接口:

/**
 *  文本输入控件中的文本内容
 */
@property (nonatomic, copy)   NSString *text;

/**
 *  文本输入控件中的文本选中范围
 */
@property (nonatomic, assign) NSRange selectedRange;

/**
 *  委托对象
 */
@property (nonatomic, weak) id<YWMessageInputViewDelegate> messageInputViewDelegate;
  • 其中 textselectedRange 这两个属性的 gettersetter 都要关联文本输入控件:

    - (NSString *)text {
          return self.inputTextView.text;
      }
      - (void)setText:(NSString *)text {
          self.inputTextView.text = text;
      }
      // selectedRange 同理省略
  • messageInputViewDelegate 属性是对委托对象的弱引用,首先需要实现该属性,之后需负责在适当时机调用 YWMessageInputViewDelegate 中定义的方法:

    @synthesize messageInputViewDelegate = _messageInputViewDelegate;

协议中定义了两个可选接口,通知应该开始或结束监听系统的键盘事件:

- (void)beginListeningForKeyboard;
- (void)endListeningForKeyboard;

回调委托对象 messageInputViewDelegate

消息输入控件委托协议 YWMessageInputViewDelegate 中定义了两类接口:

  • 一类是类似 UITextViewDelegate 的文本输入控件相关的接口,当 UITextViewDelegate 的方法被调用时,则需要转发调用 YWMessageInputViewDelegate中对应的方法:

    - (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
        BOOL shouldBeginEditing = YES;
        id<YWMessageInputViewDelegate> delegate = self.messageInputViewDelegate;
        if( [delegate respondsToSelector:@selector(messageInputViewShouldBeginEditing:)  ] ) {
           shouldBeginEditing = [delegate messageInputViewShouldBeginEditing:self];
        }
        return shouldBeginEditing;
    }
  • 另一类为通知控件高度变化的接口:

    /**
     *  输入栏高度发生变更
     */
    - (void)messageInputView:(UIView<IYWMessageInputView> *)inputView heightOfBarDidChange:(CGFloat)height;
    
    /**
     *  输入栏底部区域高度发生变更,如键盘高度或插件面板高度发生变更
     */
    - (void)messageInputView:(UIView<IYWMessageInputView> *)inputView heightOfKeyboardDidChange:(CGFloat)height;

    例如键盘出现时则需要更新控件的 frame 同时通知委托对象:

    - (void)keyboardWillShow:(NSNotification *)notification
    {
        NSDictionary *userInfo = [notification userInfo];
        CGRect keyboardEndRect = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    
        // 根据键盘高度更新控件本身的 frame
    
        if ([self.messageInputViewDelegate respondsToSelector:@selector(messageInputView:heightOfKeyboardDidChange:)]) {
        // 通知委托对象
        [self.messageInputViewDelegate messageInputView:self heightOfKeyboardDidChange:height];
        }
    }

替换消息输入控件

创建控件实例后赋值给 YWConversationViewControllerUIView<IYWMessageInputView> *messageInputView 属性即可使之生效, messageInputViewDelegate 属性同时会被自动设置:

SPMessageInputView *messageInputView = [[SPMessageInputView alloc] init];
conversationViewController.messageInputView = messageInputView;

其它说明

  • 预置的消息输入控件实现了发送消息输入状态等额外功能,自己实现时仍可通过调用 YWConversationViewController 的接口自行实现
  • 协议不强制要求兼容原输入控件的插件,但如果需要,仍可考虑复用插件以简化工作量

FAQ

关于此文档暂时还没有FAQ
返回
顶部