textkit相关做图文混排键盘

无论是富媒体输入还是聊天表情输入,都经常切换系统键盘和自定义输入View。跟Android不一样的是,iOS需要在输入控件如UITextView聚焦才能出现键盘,默认情况下一旦输入控件失焦点有没有切换到其他输入控件的时候,键盘随之消失。尽管,可以通过text属性添加响应内容,但是没有光标的位置提示总是个缺陷。

如腾讯的微信和手Q的iOS版都是没有很好处理光标问题,特别是微信iOS版的表情输入还是显示“[/微笑]”字符串。还好我看到的新浪微博对这个处理perfect。那么以下就是开始我们的主题--InputView.

Scenes:

  1. 输入框的键盘消失后,焦点还在。
  2. 输入框的能够显示表情。
  3. 获取输入框的内容时候,表情转换成对应字符串。
  4. 表情输入和系统键盘切换。

Think:

  1. 默认情况下,系统盘消失后UITextViewUITextField的焦点都会消失,这种情况不像Android开发可以单独呼出键盘和降下键盘,只能选择InputView。
  2. UITextView添加表情通过NSTextAttachment.image这个属性插入图片。
  3. 显示了表情后,获取带表情内容需要切换成对应字符串,继承NSTextAttachment的子类多定义一个NSString类型emotionStr,在编写一个NSAttributeString的Category进行处理字符转换。
  4. 切换系统键盘和表情键盘通过监听键盘的Show和Hide的通知,将UITextViewUITextField的InputView设置成nil。
  5. 并且使用自定义的UIView作为UITextViewUITextFieldinputAccessoryView属性作为切换键盘按钮。

Step Processes:

1.以UITextview为例,在Storyboard设计UI如下图。



2.关联自定义UIView作为inputAccessoryView和实例化表情面板

    -(void)viewDidLoad {
        [super viewDidLoad];
        [self.toolBarView removeFromSuperview];//主要因为inputAccessoryView的view不能在storyboard  
        self.testTv.inputAccessoryView = self.toolBarView;
        //isKeyboard = YES;
        if ( !faceBoard) {
            faceBoard = [[FaceBoard alloc] init];
            faceBoard.delegate = self;
            faceBoard.inputTextView = self.testTv;
            }   
    }

3.实现系统键盘的表情键盘

-(void)keyboardDidHide:(NSNotification *)notificati {

    if (isEmotionShow||isKeyboard) {
        [self.testTv becomeFirstResponder];
    }

}  

    -(IBAction)switchBt:(id)sender {
        UIButton *button = sender;

        if (!isEmotionShow) {
            [button setImage:[UIImage imageNamed:@"board_system"] forState:UIControlStateNormal];
               isEmotionShow = YES;
            isKeyboard = NO;
            self.testTv.inputView = faceBoard;
            self.testTv resignFirstResponder];

        }else{
            [button setImage:[UIImage imageNamed:@"board_emoji"] forState:UIControlStateNormal];
            isEmotionShow = NO;
            isKeyboard = YES;
            self.testTv.inputView = nil;
            [self.testTv resignFirstResponder];

         }
    }

4.UITextview插入图片

if (self.inputTextView){
    NSMutableString *faceString = [[NSMutableString alloc]initWithString:self.inputTextView.text];
    [faceString appendString:[_faceMap objectForKey:[NSString stringWithFormat:@"%03d", i]]];

    EmotionTextAttachment *emotionTextAttachment = [EmotionTextAttachment new];
    emotionTextAttachment.emotionStr = [_faceMap objectForKey:[NSString stringWithFormat:@"%03d", i]];
    emotionTextAttachment.image = [UIImage imageNamed:[NSString stringWithFormat:@"%03d", i]];
    //存储光标位置
    location = (int)self.inputTextView.selectedRange.location;
    //插入表情
    [self.inputTextView.textStorage insertAttributedString:[NSAttributedString attributedStringWithAttachment:emotionTextAttachment] atIndex:self.inputTextView.selectedRange.location];
    //光标位置移动1个单位
    self.inputTextView.selectedRange = NSMakeRange(location+1, 0);

    [delegate textViewDidChange:self.inputTextView];
 }

5.编写NSAttributedString的Catergory实现获取表情对应的字符串

@implementation NSAttributedString (Emotion)  

-(NSString *) mgo_getPlainString {

    NSMutableString *sourceString = [NSMutableString stringWithString:self.string];

    __block NSUInteger index = 0;

    [self enumerateAttribute:NSAttachmentAttributeName inRange:NSMakeRange(0, self.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
           if (value && [value isKindOfClass:[EmotionTextAttachment class]]) {
               [sourceString replaceCharactersInRange:NSMakeRange(range.location + index, range.length) withString:((EmotionTextAttachment *) value).emotionStr];
        index += ((EmotionTextAttachment *) value).emotionStr.length - 1;
    }
    }];

    return sourceString;
}
@end

6.调用扩展方法

NSString *inputString;
if ( self.inputTextView ) { 
    inputString = [self.inputTextView.attributedText mgo_getPlainString]; 
}

7.最终的效果如下


Demo地址

https://github.com/minggo620/iOSInputView.git




文/minggo(简书作者)
原文链接:http://www.jianshu.com/p/bd04a17464ef
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值