博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
仿微信表情输入
阅读量:7100 次
发布时间:2019-06-28

本文共 5353 字,大约阅读时间需要 17 分钟。

哇哦,好久没有写过博客了,前段时间太忙了。最近项目需求,要实现一个类似微信的的表情输入,于是把微信的表情扒拉出来,实现了一把。可以从这里下载。看起来表情输入没有多少东西,不外乎就是用NSTextAttachment来实现图文混排,结果在实现的过程中遇到了很多小问题,接下来会一一介绍遇到过的坑。先上一张效果图:

效果

一、实现表情选择View(WKExpressionView)

具体的实现就不细说了,主要功能就是点击表情时,将对应表情的图片名称通知给delegate。

二、实现表情textView(WKExpressionTextView)

WKExpressionTextView继承自UITextView, 提供 

- (void)setExpressionWithImageName:(NSString *)imageName fontSize:(CGFloat)fontSize方法,用于根据图片插入表情。 具体实现:

//富文本    WKExpressionTextAttachment *attachment = [[WKExpressionTextAttachment alloc] initWithData:nil ofType:nil];    UIImage *image = [UIImage imageNamed:imageName];    attachment.image = image;    attachment.text = [WKExpressionTool getExpressionStringWithImageName:imageName];    attachment.bounds = CGRectMake(0, 0, fontSize, fontSize);    NSAttributedString *insertAttributeStr = [NSAttributedString attributedStringWithAttachment:attachment];    NSMutableAttributedString *resultAttrString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];    //在当前编辑位置插入字符串    [resultAttrString insertAttributedString:insertAttributeStr atIndex:self.selectedRange.location];    NSRange tempRange = self.selectedRange;    self.attributedText = resultAttrString;    self.selectedRange = NSMakeRange(tempRange.location + 1, 0);    [self.textStorage addAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:_defaultFontSize]} range:NSMakeRange(0, self.attributedText.length)];    [self scrollRangeToVisible:self.selectedRange];    [self textChanged];

 其中WKExpressionTextAttachment继承自NSTextAttachment, 并新增text字段,为了保存表情对应的文本,用于复制粘贴操作。

@interface WKExpressionTextAttachment : NSTextAttachment@property (nonatomic, copy) NSString *text;@end

 WKExpressionTool的提供将普通字符串转换为富文本的方法,主要用于复制时生成表情。 

主要方法

+ (NSAttributedString *)generateAttributeStringWithOriginalString:(NSString *)originalString fontSize:(CGFloat)fontSize{    NSError *error = NULL;    NSMutableAttributedString *resultAttrString = [[NSMutableAttributedString alloc] initWithString:originalString];    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\[[a-zA-Z0-9\u4e00-\u9fa5]{1,}\\]" options:NSRegularExpressionAllowCommentsAndWhitespace error:&error];    NSArray *results = [regex matchesInString:originalString options:NSMatchingReportCompletion range:NSMakeRange(0, originalString.length)];    if (results) {        for (NSTextCheckingResult *result in results.reverseObjectEnumerator) {            NSRange resultRange = [result rangeAtIndex:0];            NSString *stringResult = [originalString substringWithRange:resultRange];            NSLog(@"%s %@\n", __FUNCTION__, stringResult);            NSAttributedString *expressionAttrString = [self getAttributeStringWithExpressionString:stringResult fontSize:fontSize];            [resultAttrString replaceCharactersInRange:resultRange withAttributedString:expressionAttrString];        }    }    return resultAttrString;}

 

/** *  通过表情生成富文本 * *  @param expressionString 表情名 *  @param fontSize         对应字体大小 * *  @return 富文本 */+ (NSAttributedString *)getAttributeStringWithExpressionString:(NSString *)expressionString fontSize:(CGFloat)fontSize{    NSString *imageName = [self getExpressionStringWithImageName:expressionString];    WKExpressionTextAttachment *attachment = [[WKExpressionTextAttachment alloc] initWithData:nil ofType:nil];    UIImage *image = [UIImage imageNamed:imageName];    attachment.image = image;    attachment.text = [WKExpressionTool getExpressionStringWithImageName:imageName];    attachment.bounds = CGRectMake(0, 0, fontSize, fontSize);    NSAttributedString *appendAttributeStr = [NSAttributedString attributedStringWithAttachment:attachment];    return appendAttributeStr;}

 

至此,基本功能实现完成。 接下来说说遇到的小问题

  • 编辑是应该对应selectedRange
  • 复制粘贴操作需要重新实现
  • textView在插入NSTextAttachment后,会默认把font的size修改为12,需要记录默认的size

对应selectedRange操作

具体的操作查看源码

重新实现copy、cut方法

进行复制、粘贴操作会发现,不能对图片进行复制,所以需要自己重写copy、cut方法

- (void)copy:(id)sender{    NSAttributedString *selectedString = [self.attributedText attributedSubstringFromRange:self.selectedRange];    NSString *copyString = [self parseAttributeTextToNormalString:selectedString];    UIPasteboard *pboard = [UIPasteboard generalPasteboard];    if (copyString.length != 0) {        pboard.string = copyString;    }}- (void)cut:(id)sender{    [self copy:sender];    NSMutableAttributedString *originalString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];    [originalString deleteCharactersInRange:self.selectedRange];    self.attributedText = originalString;    NSLog(@"--%@", NSStringFromRange(self.selectedRange));    [self textChanged];}

 

记录默认font的size

利用实例变量defaultFontSize,在WKExpressionTextView实例化时记录self.font.pointSize,以后需要取font的size时,直接取defaultFontSize

@interface WKExpressionTextView : UITextView @property (nonatomic, assign) CGFloat defaultFontSize;@end@implementation WKExpressionTextView{    CGFloat _defaultFontSize;}- (void)awakeFromNib{    [self setup];}- (instancetype)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        [self setup];    }    return self;}- (void)setup{    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange:) name:UITextViewTextDidChangeNotification object:self];    _defaultFontSize = self.font.pointSize;    self.delegate = self;}

 

转载于:https://www.cnblogs.com/pretty-guy/p/5427224.html

你可能感兴趣的文章
Java -- 获取MAC地址
查看>>
Visual Prolog 的 Web 专家系统 (1)
查看>>
void 指针的转换
查看>>
再议Unity优化
查看>>
localhost兼容js不能用
查看>>
Makefile 10——打造更专业的编译环境-huge项目
查看>>
Create and Call HttpHandler in SharePoint
查看>>
pymysql.err.InternalError: (1054, "Unknown column 'None' in 'field list'")
查看>>
树莓派与window 10组成的物联网核心:让人失望
查看>>
Servlet的异常处理
查看>>
支付宝 app支付 沙盘使用
查看>>
Redis持久化配置-AOF
查看>>
计算机网络的应用层简单介绍:
查看>>
需求管理之客户需求何时休?
查看>>
Java进化? Kotlin初探与集成Android项目
查看>>
URL中的#
查看>>
CentOS自带mysql配置(密码更改、端口开放访问、添加进系统启动项)
查看>>
MYSQL中动态行数据转列数据
查看>>
anchor_target_layer中的bounding regression
查看>>
[转]怎么解决输入流和输出流编码问题
查看>>