美文网首页
UITextView-使用集合

UITextView-使用集合

作者: 思念那年慕云 | 来源:发表于2017-02-26 18:50 被阅读393次
    键盘弹出来时,改变工具栏的高度,
    想要实现键盘和工具栏一起往上移动的效果,
    
    添加动画,调用[self.view layoutIfNeeded];方法即可
    
    image.png

    注意:

        #UITextView的高度,一定要大于输入文字的高度,不然输入文字的时候会晃动,而且还会显示不全哦。所以富文本的时候高度是个大事。
        UITextView *titleView = [[UITextView alloc] initWithFrame:CGRectMake(15, 20, SCREEN_WIDTH-30, 30)];
        titleView.font = [UIFont systemFontOfSize:24];
        #系统Bug。(UITextView文字和占位文字偏移了10的间距)
        titleView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, -10);
        titleView.backgroundColor=[UIColor yellowColor];
        [self.view addSubview:titleView];
    
    1,解决textView输入内容的时候,光标下沉。
    //解决textView输入内容的时候,光标下沉。
        self.textField_t.textContainerInset = UIEdgeInsetsMake(5, 0, 0, 0);
    
    2,输入了100行,然后输入第一行内容,那么会自动跑到底部。这句就是为了防止回到底部
        //输入了100行,然后输入第一行内容,那么会自动跑到底部。这句就是为了防止回到底部
        self.textView_c.layoutManager.allowsNonContiguousLayout = NO;
    
    3,自定义view中textview滚动失效 iOS(自定义view放在了一个VC中)
    #解决方法:
    在VC中
    -(void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
    
        //自定义view中的TextView的scrollEnabled需要在VC加载结束后手动打开一次,不然会把默认YES改为NO。
        self.detailView.textView_detail.scrollEnabled = YES;
    }
    
    4,添加图片附件
        //添加图片附件
        NSTextAttachment *attach = [[NSTextAttachment alloc] init];
        attach.image = [UIImage imageNamed:@"1.jpg"];
        attach.bounds = CGRectMake(0, 0, 100, 100);
        //附件是不可变属性字符串
        NSAttributedString *attributedString = [NSAttributedString attributedStringWithAttachment:attach];
        NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:@"点击分手克里斯丁建安费垃圾啊啥都离开房间撒的李开复"];
        [attributedStr insertAttributedString:attributedString atIndex:attributedStr.length];
    
        self.textView.attributedText = attributedStr;
    
    5,获取光标位置
    #注意:使用时候判断是否为空:
        NSRange rg = self.textView.selectedRange;
         if (rg.location != NSNotFound)
        {
            NSLog(@"光标位置:%d",rg.location);
        }
    

    6,iOS中TextView显示HTML文本

    7,输入时上下晃动

    CGRect line = [textView caretRectForPosition:textView.selectedTextRange.start];
        CGFloat overflow = line.origin.y + line.size.height    - ( textView.contentOffset.y + textView.bounds.size.height - textView.contentInset.bottom - textView.contentInset.top );
        if ( overflow > 0 ) {
            // We are at the bottom of the visible text and introduced a line feed, scroll down (iOS 7 does not do it)
            // Scroll caret to visible area
            CGPoint offset = textView.contentOffset;
            offset.y += overflow + 7;
            // leave 7 pixels margin
            // Cannot animate with setContentOffset:animated: or caret will not appear
            [UIView animateWithDuration:.2 animations:^{
                [textView setContentOffset:offset];
            }];
        }
    
    8,UITextView加载HTML数据(左间距没有调试成功,暂用wkwebView.)
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 10, [UIScreen mainScreen].bounds.size.width - 20, [UIScreen mainScreen].bounds.size.height - 20)];
        textView.delegate = self;
        textView.editable = NO; // 非编辑状态下才可以点击Url]
    //    textView.fontFloat = 18.;
        NSString *textStr=@"<p>现在互联网,断章取义的东西大家最喜欢玩了,本来是个很严肃很励志的一句话,但是把头尾一截,就变得很有趣味了</p><p><br/></p><p>先订一个能达到的小目标(严肃认真脸.jpg)</p><p>比方说我先挣它一个亿(严肃轻松脸.png)</p><p><img src=\"http://img.woshipm.com/TTW_QUESTION_201608_20160829170712_0539.jpg\" title=\"\" width=\"385\" height=\"415\" style=\"width: 385px; height: 415px;\"/></p><p>首尾的强大反差给人一种无奈到好笑的感觉,跟比尔盖茨很有名的那张3秒赚辆兰博基尼有异曲同工之妙。</p><p><br/></p><p>说的随便点吧,就是大家觉得这东西好玩搞笑,极具讽刺性,跟大家的生活现状形成强烈的对比,明明就是苦逼屌丝一辈子赚不到一千万的角儿,却要看着人家定个小目标随便弄他一个亿,我的妈呀,人与人之间的差别距离好几个爹呀。</p><p>互联网现在信息传递快,大家爱自嘲、爱起哄,像这种能够开名人玩笑,为生活补充点乐子的事,而且还能表达一下自己对生活的挖苦、讽刺,所以转了也就转了<br/></p>";
    //    NSString *linkStr = [textView.text substringWithRange:range];
        
        NSMutableAttributedString *attributedString = [self changeHtmlStringToAttributeString:textStr];
    //    [attributedString addAttribute:NSLinkAttributeName value:@"http://img.taopic.com/uploads/allimg/111231/6755-11123114022199.jpg" range:NSMakeRange(0, 6)];
    
        textView.attributedText = attributedString;
        [self.view addSubview:textView];
    
    #测试
    (
    
     self.jq_textView.delegate = self;
        self.jq_textView.editable = NO; // 非编辑状态下才可以点击Url]
        //    textView.fontFloat = 18.;
        NSString *textStr=@"<div style=\"margin:75px;\"><h2 style=\"font-size: 13px;color: #888;\">会员权益简介 -----------------</h2><div style=\"padding-left:70px;\"><h2 style=\"font-size: 13px;color: #888;\">会员专享价</h2><h3 style=\"font-size: 13px;color: #999;margin: 30px 35 0 0;\">权益说明</h3><p style=\"font-size: 13px;color: #999;margin: 0 35 15px 0;\">商品促销信息以商品详情页“促销”栏中的信息为准;商品的具体售价以订单结算页价格为准;如您发现活动商品售价或促销信息有异</p><h3 style=\"font-size: 13px;color: #999;margin:10px 35 0 0;\">权益等级</h3><p style=\"font-size: 13px;color: #999;margin: 0 35 15px 0;\">信息以商品详情页“促销”栏</p><h3 style=\"font-size: 13px;color: #999;margin: 10px 35 0 0;\">其他说明</h3><p style=\"font-size: 13px;color: #999;margin: 0 35 15px 0;\">商品促销信息以商品详情页“促销”栏中的信息为准;商品的具体售价以订单结算页价格为准;如您发现活动商品售价或促销信息有异</p></div></div>";
        //    NSString *linkStr = [textView.text substringWithRange:range];
        
        NSMutableAttributedString *attributedString = [self changeHtmlStringToAttributeString:textStr];
        
        self.jq_textView.attributedText = attributedString;
    
    
      )
    
    
    
    }
    
    -(NSMutableAttributedString *)changeHtmlStringToAttributeString:(NSString *)htmlString{
        NSString *newString = htmlString;
        
        
        //图片自适应宽高,只限制图片的最大显示宽度,这样就能做到自适应
        newString =[NSString stringWithFormat:@"<html>"
                    "<head>"
                    
                    "</style>"
                    "<style>*{margin:3px 0px 3px 0px;padding:0 ;max-width:%f;}</style>"
                    "</head>"
                    "<body>%@</body>"
                    "</html>",self.view.frame.size.width-30,newString];
        NSData *data = [newString dataUsingEncoding:NSUnicodeStringEncoding];
        
        NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
        NSMutableAttributedString *htmlAttribute = [[NSMutableAttributedString alloc] initWithData:data
                                                                                           options:options
                                                                                documentAttributes:nil
                                                                                             error:nil];
        
        NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        
        //设置文字的行间距
        [paragraphStyle setLineSpacing:5];
        
        [htmlAttribute addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [htmlAttribute length])];
        //设置文字的颜色
        [htmlAttribute addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, htmlAttribute.length)];
        
        //设置文字的大小
        [htmlAttribute addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:14] range:NSMakeRange(0, htmlAttribute.length)];
        
        return htmlAttribute;
        
    
    
    #测试
    (
          NSString *newString = htmlString;
        
        NSData *data = [newString dataUsingEncoding:NSUnicodeStringEncoding];
        
        NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
        NSMutableAttributedString *htmlAttribute = [[NSMutableAttributedString alloc] initWithData:data
                                                                                           options:options
                                                                                documentAttributes:nil
                                                                                             error:nil];
        
        return htmlAttribute;
    )
    }
    
    9,自定义 UITextView 关键字高亮与点击检测
    10,替换属性字符串中的图片为字符
    #:属性字符串attributeString
        //方法一
    //    NSMutableString *plainString = [NSMutableString stringWithString:attributeString.string];
    //    __block NSUInteger base = 0;
    //    [self enumerateAttribute:NSAttachmentAttributeName inRange:NSMakeRange(0, self.length)
    //                     options:0
    //                  usingBlock:^(LiuqsTextAttachment *value, NSRange range, BOOL *stop) {
    //                      if (value) {
    //                          [plainString replaceCharactersInRange:NSMakeRange(range.location + base, range.length)
    //                                                     withString:value.emojiTag];
    //                          base += value.emojiTag.length - 1;
    //                      }
    //                  }];
        
        //方法二(推荐)
        NSMutableAttributedString *mutableAttributeString = [[NSMutableAttributedString alloc] initWithAttributedString:attributeString];
        [mutableAttributeString enumerateAttribute:@"NSAttachment" inRange:NSMakeRange(0, self.length) options:0 usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {
            
            NSLog(@"value===%@",value);
            NSLog(@"range===%@",NSStringFromRange(range));
    
            if ([value isKindOfClass:[NSTextAttachment class]]) {
                LiuqsTextAttachment *attachment = (LiuqsTextAttachment *)value;
                [mutableAttributeString replaceCharactersInRange:range withString:attachment.emojiTag];
            }
            
        }];
        
        return [mutableAttributeString string];
    
    11,清空UItextView的所有内容
    self.toolView.jq_inputView.text = @" ";
    [self.toolView.jq_inputView deleteBackward]; //删除一个字节
    
    12,UITextView/UITextField检测并过滤Emoji表情符号
    当用户切换键盘为Emoji表情时,输入的表情不响应(即表情符号不显示到UITextView或UITextField)。这里可以通过UITextView或UITextField的回调和是否为emoji键盘:
    
     /*
     *第一种方法,简单粗暴
     */
     - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
     {
         // 不让输入表情
         if ([textView isFirstResponder]) {
             if ([[[textView textInputMode] primaryLanguage] isEqualToString:@"emoji"] || ![[textView textInputMode] primaryLanguage]) {
                 NSLog(@"输入的是表情,返回NO");
                 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"警告!" message:@"不能输入表情" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定",nil];
                 [alertView show];
                 return NO;
             }
         }
         return YES;
     }
    
    为避免当用户通过中文键盘输入中文“哈哈”后出现可选文字中选中的Emoji笑脸,最后在- (void)textFieldDidEndEditing:(UITextField *)textField方法中统一通过检查最终字符串textField/textView.text的内容,通过Emoji筛unicode编码来判断是否存在Emoji表情,如果存在则提醒用户做修改。
    
     //在输入完成时,调用下面那个方法来判断输入的字符串是否含有表情
     - (void)textFieldDidEndEditing:(UITextField *)textField
     {
         if ([self stringContainsEmoji:textField.text]) {
             NSLog(@"含有表情");
             UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"警告!" message:@"输入内容含有表情,请重新输入" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定",nil];
             [alertView show];
             textField.text = @"";
             [textField becomeFirstResponder];
         }else {
             NSLog(@"不含有表情");
         }
    
     }
    
     /*
      *第二种方法,利用Emoji表情最终会被编码成Unicode,因此,
      *只要知道Emoji表情的Unicode编码的范围,
      *就可以判断用户是否输入了Emoji表情。
      */
     - (BOOL)stringContainsEmoji:(NSString *)string
     {
         // 过滤所有表情。returnValue为NO表示不含有表情,YES表示含有表情
         __block BOOL returnValue = NO;
         [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
    
             const unichar hs = [substring characterAtIndex:0];
             // surrogate pair
             if (0xd800 <= hs && hs <= 0xdbff) {
                 if (substring.length > 1) {
                     const unichar ls = [substring characterAtIndex:1];
                     const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                     if (0x1d000 <= uc && uc <= 0x1f77f) {
                         returnValue = YES;
                     }
                 }
             } else if (substring.length > 1) {
                 const unichar ls = [substring characterAtIndex:1];
                 if (ls == 0x20e3) {
                     returnValue = YES;
                 }
             } else {
                 // non surrogate
                 if (0x2100 <= hs && hs <= 0x27ff) {
                     returnValue = YES;
                 } else if (0x2B05 <= hs && hs <= 0x2b07) {
                     returnValue = YES;
                 } else if (0x2934 <= hs && hs <= 0x2935) {
                     returnValue = YES;
                 } else if (0x3297 <= hs && hs <= 0x3299) {
                     returnValue = YES;
                 } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                    //想过滤的字符可以在这里做处理
                    if (![substring isEqualToString:@"®"]) {
                        returnValue = YES;
                    }
                 }
             }
         }];
         return returnValue;
     }
    
    
    13,UITextView插入图片时,通常会想在前后插入换行(\n),但是呢,如果加了行高之类的东西,那么就尴尬了,因为计算的高度会出问题。
    #方案一:在图片前后分别再插入一个附件,高度为0或1,宽度为屏幕宽。
    #first,尴尬了,附件有个默认的高度,大概10-15左右吧,
    这个高度是去不掉的,而且就算高度为0,还是可以点击到附件。
    如果想做点击图片放大的话,这又是个难题。
    #final,放弃方案一。
    
    #方案二:回归添加换行(\n)
            /*
                1,取图片前一位,如果是图片,那么就不添加回车,如果不是图片,那么就添加回车。
                2,取前一位时注意图片是第一位的情况。
                3,经测试得到,一个回车是20的高度。如果有一个回车就在totalImageHeight的基础上添加20。
                4,注意属性字符要准备2份,一份用来展示(带回车),一份把图片替换为空(不带回车),因为totalImageHeight已经把回车的高度加上了。计算纯文本就可以了。
                5,替换文本后需要重新设置富文本属性,不然会恢复初始化状态,行高间距字体大小都没了。
                6,连续两张图片的算一个间距,所以这里要减去有多少个连续的图片,最后测试选择一个连续的两张图-10的间距。
                7,换行的模式选择NSLineBreakByCharWrapping,因为这样可以兼容到字母、数字。
                   举例:paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
                8, 根据URL找到指定缓存(如果存在的话)
                   UIImage* image = [[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:url];
                9,插入图片原理:看SDWebImage中是否有缓存图片,有则把正则匹配的图片范围直接替换为图片,否则,先默认插入一个宽高均为SCREEN_WIDTH-25的附件,然后SDWebImage异步下载图,下载成功之后,判断找到对应的附件,替换,textView高度减去差值,重新添加到tableview的头部。
             
             */
    
    
    14,系统UITextView可以开始识别手机号、网址等。
    textView.delegate = self;
    textView.dataDetectorTypes = UIDataDetectorTypeLink; //开启识别链接
    
    UIDataDetectorTypePhoneNumber  :识别手机号
    UIDataDetectorTypeLink  :识别链接
    UIDataDetectorTypeAll  :识别所有
    
    
    #点击链接会走这个方法
    //链接委托(链接最好用一个括号括起来,或者在链接后面加个空格。)
    - (BOOL)textView:(UITextView*)textView
        shouldInteractWithURL:(NSURL*)URL
                      inRange:(NSRange)characterRange
    {
        NSLog(@"URL tap handle:%@", URL);
    
        return YES; //返回yes,点击链接的时候就会自动打开。
    }
    
    #点击附件会走这里的方法
    /*
     附件委托新方法。
     返回YES,可以从下面弹出复制图片或保存图片,但是呢,不是很好看。
     */
    - (BOOL)textView:(UITextView*)textView
        shouldInteractWithTextAttachment:(NSTextAttachment*)textAttachment
                                 inRange:(NSRange)characterRange
                             interaction:(UITextItemInteraction)interaction
    {
        //获取附件
        CustomTextAttachMent* attachment = (CustomTextAttachMent*)textAttachment;
    
        NSLog(@"%@", attachment.imgURL); //获取原图URL
    
    #这里我使用HJPhotoBrowser做了点击图片放大的功能。
        self.clickImgURL = attachment.imgURL;
        self.clickImg = attachment.image;
    
        HJPhotoBrowser* photoBrowser = [HJPhotoBrowser new];
        photoBrowser.delegate = self;
        //    photoBrowser.currentImageIndex = indexPath.item;
        photoBrowser.imageCount = 1;
        photoBrowser.sourceImagesContainerView = self.view;
    
        [photoBrowser show];
    
        return NO;
    }
    
    
    15,UITextView实现左右点击效果

    感觉两个手势就搞定了,待定(该博客还没看)

    16,UITextView实现富文本
            /*
             1,取图片前一位,如果是图片,那么就不添加回车,如果不是图片,那么就添加回车。
             2,取前一位时注意图片是第一位的情况。
             3,经测试得到,一个回车是20的高度。如果有一个回车就在totalImageHeight的基础上添加20。
             4,注意属性字符要准备2份,一份用来展示(带回车),一份把图片替换为空(不带回车),因为totalImageHeight已经把回车的高度加上了。计算纯文本就可以了。
             5,替换文本后需要重新设置富文本属性,不然会恢复初始化状态,行高间距字体大小都没了。
             6,连续两张图片的算一个间距,所以这里要减去有多少个连续的图片,最后测试选择一个连续的两张图-10的间距。
             7,换行的模式选择NSLineBreakByCharWrapping,因为这样可以兼容到字母、数字。
             举例:paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
             8, 根据URL找到指定缓存(如果存在的话)
             UIImage* image = [[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:url];
             9,插入图片原理:看SDWebImage中是否有缓存图片,有则把正则匹配的图片范围直接替换为图片,否则,先默认插入一个宽高均为SCREEN_WIDTH-25的附件,然后SDWebImage异步下载图,下载成功之后,判断找到对应的附件,替换,textView高度减去差值,重新添加到tableview的头部。
             
             10,注意替换SDWebImage下载完成的图片时,要重新创建一个CustomTextAttachMent,不然一张图的时候,第一次进入显示失败。
             */
    

    相关文章

      网友评论

          本文标题:UITextView-使用集合

          本文链接:https://www.haomeiwen.com/subject/qfnvwttx.html