ios uitextview 滚动复制

 我来答
兄弟连田心9号
2020-12-26 · TA获得超过38万个赞
知道顶级答主
回答量:12.3万
采纳率:87%
帮助的人:1.2亿
展开全部

UITextView是ios的富文本编辑控件,除了文字还可以插入图片等。今天主要介绍一下UITextView对自定义表情的处理。

1、首先识别出文本中的表情文本,然后在对应的位置插入NSTextAttachment对象,该对象存放的就是自定义表情。

1 static NSString *emojiTextPttern = @"\\[[0-9a-zA-Z\\u4e00-\\u9fa5]+\\]"; 2  3 _emojiDic = @{@"[大笑]":@"smile",@"[爱心]":@"love"}; 4  5 -(NSMutableAttributedString*)getEmojiText:(NSString*)content{ 6     NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:content attributes:self.typingAttributes]; 7     static NSRegularExpression *regExpress = nil; 8     if(regExpress == nil){ 9         regExpress = [[NSRegularExpression alloc]initWithPattern:emojiTextPttern options:0 error:nil];10     }11     //通过正则表达式识别出emojiText12     NSArray *matches = [regExpress matchesInString:content options:0 range:NSMakeRange(0, content.length)];13     if(matches.count > 0){14         for(NSTextCheckingResult *result in [matches reverseObjectEnumerator]){15             NSString *emojiText = [content substringWithRange:result.range];16             //构造NSTextAttachment对象17             NSTextAttachment *attachment = [self createEmojiAttachment:emojiText];18             if(attachment){19                 NSAttributedString *rep = [NSAttributedString attributedStringWithAttachment:attachment];20                 //在对应的位置替换21                 [attributedString replaceCharactersInRange:result.range withAttributedString:rep];22             }23         }24     }25     return attributedString;26 }

2、构造NSTextAttachment的过程为:

1 -(NSTextAttachment*)createEmojiAttachment:(NSString*)emojiText{ 2     if(emojiText.length==0){ 3         return nil; 4     } 5     NSString *imageName = _emojiDic[emojiText]; 6     if(imageName.length == 0){ 7         return nil; 8     } 9     UIImage *image = [UIImage imageNamed:imageName];10     if(image == nil){11         return nil;12     }13     //把图片缩放到符合当前textview行高的大小14     CGFloat emojiWHScale = image.size.width/1.0/image.size.height;15     CGSize emojiSize = CGSizeMake(self.font.lineHeight*emojiWHScale, self.font.lineHeight);16     UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, emojiSize.width, emojiSize.height)];17     imageView.image = image;18     //防止模糊19     UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, [UIScreen mainScreen].scale);20     [imageView.layer renderInContext:UIGraphicsGetCurrentContext()];21     UIImage *emojiImage = UIGraphicsGetImageFromCurrentImageContext();22     UIGraphicsEndImageContext();23     EmojiTextAttachment *attachment = [[EmojiTextAttachment alloc]init];24     attachment.image = emojiImage;25     attachment.emojiText = emojiText;26     attachment.bounds = CGRectMake(0, -3, emojiImage.size.width, emojiImage.size.height);27     return attachment;28 }

其中EmojiTextAttachment继承了NSTextAttachment类,主要是为了记住自定义表情对应的emojiText,在后面实现copy和cut需要用到。EmojiTextAttachment声明为:

1 @interface EmojiTextAttachment : NSTextAttachment2 3 /**4  保存emojiText的值5  */6 @property (nonatomic, strong) NSString *emojiText;7 @end

3、实现对自定义表情的粘贴

重新paste方法即可

1 -(void)paste:(id)sender{ 2     UIPasteboard *defaultPasteboard = [UIPasteboard generalPasteboard]; 3     if(defaultPasteboard.string.length>0){ 4         NSRange range = self.selectedRange; 5         if(range.location == NSNotFound){ 6             range.location = self.text.length; 7         } 8         if([self.delegate textView:self shouldChangeTextInRange:range replacementText:defaultPasteboard.string]){ 9            NSAttributedString *newAttriString = [self getEmojiText:defaultPasteboard.string];10            [self insertAttriStringToTextview:newAttriString];11         }12         return;13     }14     [super paste:sender];15 }16 17 -(void)insertAttriStringToTextview:(NSAttributedString*)attriString{18     NSMutableAttributedString *mulAttriString = [[NSMutableAttributedString alloc]initWithAttributedString:self.attributedText];19     NSRange range = self.selectedRange;20     if(range.location == NSNotFound){21         range.location = self.text.length;22     }23     [mulAttriString insertAttributedString:attriString atIndex:range.location];24     self.attributedText = [mulAttriString copy];25     self.selectedRange = NSMakeRange(range.location+attriString.length, 0);26 }

4、实现自定义表情的拷贝和剪切

拷贝和剪切自定义表情的时候,不是获取自定义表情对应的图片而是自定义表情对应的emojiText,这也是我们在上面要定义EmojiTextAttachment类的原因。具体代码如下:

1 -(void)copy:(id)sender{ 2     NSRange range = self.selectedRange; 3     NSString *content = [self getStrContentInRange:range]; 4     if(content.length>0){ 5         UIPasteboard *defaultPasteboard = [UIPasteboard generalPasteboard]; 6         [defaultPasteboard setString:content]; 7         return; 8     } 9     [super copy:sender];10 }11 -(void)cut:(id)sender{12     NSRange range = self.selectedRange;13     NSString *content = [self getStrContentInRange:range];14     if(content.length>0){15         [super cut:sender];16         UIPasteboard *defaultPasteboard = [UIPasteboard generalPasteboard];17         [defaultPasteboard setString:content];18         return;19     }20     [super cut:sender];21 }22 23 /**24  把textview的attributedText转化为NSString,其中把自定义表情转化为emojiText25 26  @param range 转化的范围27  @return 返回转化后的字符串28  */29 -(NSString*)getStrContentInRange:(NSRange)range{30     NSMutableString *result = [[NSMutableString alloc]initWithCapacity:10];31     NSRange effectiveRange = NSMakeRange(range.location,0);32     NSUInteger length = NSMaxRange(range);33     while (NSMaxRange(effectiveRange)<length) {34         NSTextAttachment *attachment = [self.attributedText attribute:NSAttachmentAttributeName atIndex:NSMaxRange(effectiveRange) effectiveRange:&effectiveRange];35         if(attachment){36             if([attachment isKindOfClass:[EmojiTextAttachment class]]){37                 EmojiTextAttachment *emojiAttachment = (EmojiTextAttachment*)attachment;38                 [result appendString:emojiAttachment.emojiText];39             }40         }41         else{42             NSString *subStr = [self.text substringWithRange:effectiveRange];43             [result appendString:subStr];44         }45     }46     return [result copy];47 }

通过上面的努力,我们已经实现了所有的功能。但是我们用起来的时候,会发现两个问题:

1、在自定义表情的后面输入文本,UITextview设置的属性(比如字体大小,颜色等)都消失,又变成了默认属性;

2、在ios 10.11系统上,长按自定义表情的时候,keyboard会退出,并且弹出保存图片的系统窗口,这样的体验也不好。

解决第一个问题:

我们在初始化的时候保存一下UITextview的typingAttributes属性,然后在每次UITextview的内容将要发生变化的时候,重置一下他的该属性。

1 @interface ViewController ()<UITextViewDelegate> 2 @property (nonatomic, strong)CustomTextView *textView; 3  4 @property (nonatomic, strong)NSDictionary *typingAttributes; 5 @end 6  7 -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{ 8     textView.typingAttributes = self.typingAttributes; 9     return YES;10 }

解决第二个问题:

只需要实现一个delegate方法就行,直接返回NO

1 -(BOOL)textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction{2     return NO;3 }

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
网易云信
2023-12-06 广告
很高兴能回答您的问题。以下是一段针对“一对一消息组件”的描述,字数在200字左右:该组件支持用户之间的私密交流,让沟通更加直接和高效。通过它,您可以向特定对象发送消息,并实时查看消息状态,包括对方是否已读或未读。同时,该组件还支持富文本消息... 点击进入详情页
本回答由网易云信提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式