• 功能需求

    在做“沃迪康”聊天功能时,甲方要求发送的网址要自动识别、并点击能自动跳转

  • 功能难点  

    在实现过程中,所有的文字都是动态获取的,设置富文本属性时,不能按照常规的方法

  • 解决方式

    • 如果只是文字,没有表情的话,可以用UILabel和UITextView来实现
    • 如果有表情的话,目前了解到比较容易的是用UITextView来实现
  • 代码实现
    • UILabelUILabel实现方式:

      本人用的第三方框架:TYAttributedLabel, 可自行去git上下载;
      
      如下,我将以自己的代码实现,讲一下自己是如何使用的,以供参考,注意,只是讲解自己的思路,无法复制使用:
      
      .导入TYAttributedLabel头文件到自己需要的地方:(本人是在.h 实现下面的代码,读者也可在.m中声明)
      @protected TYAttributedLabel *_chatText; .在.m文件中实例刚声明的_chatText,如下:
      _chatText = [[TYAttributedLabel alloc] init]; //创建实例
      _chatText.backgroundColor = [UIColor clearColor]; //设置背景色
      _chatText.delegate = self; //设置代理 _chatText.textAlignment = NSTextAlignmentLeft; //设置显示的格式--居左
      _chatText.numberOfLines = ; //设置行数不限 .给_chatText赋值--这个是个重点,请注意:
      NSString *URLStr = @"http://baidu.com这是一个url,这个url可以点击跳转到http://baidu.com的页面上"; //给URLStr赋值
      NSArray *textArray = [YZTools subStrUseURL: URLStr]; //此处请注意:YZTools是我自己平时积累方法的一个工具类, subStrUseURL这个方法是把URLStr根据URL网址来分隔成一个数组 , 下面会给出里面的代码,请耐心,分隔出来的数组如下@[@"http://baidu.com",@"这是一个url,这个url可以点击跳转到",@"http://baidu.com"]
      for (NSString *text in textArray) {
      // 根据分隔的数组,判断是否是url再调用TYAttributedLabel的方法来添加URL的颜色属性和字体大小
      if ([text hasPrefix:@"http"]) {
      [_chatText appendLinkWithText:text linkFont:[_msg textFont] linkColor:[UIColor blueColor] linkData:text];
      }else {
      [_chatText appendText:text];
      }
      } .在.m中继承TYAttributedLabel的代理 <TYAttributedLabelDelegate>,并实现代理
      #pragma mark - TYAttributedLabelDelegate - (void)attributedLabel:(TYAttributedLabel *)attributedLabel textStorageClicked:(id<TYTextStorageProtocol>)TextRun atPoint:(CGPoint)point
      {
      NSLog(@"textStorageClickedAtPoint");
      if ([TextRun isKindOfClass:[TYLinkTextStorage class]]) { NSString *linkStr = ((TYLinkTextStorage*)TextRun).linkData; if ([linkStr hasPrefix:@"http:"]) {
      [ [ UIApplication sharedApplication] openURL:[ NSURL URLWithString:linkStr]];
      }else {
      UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"点击提示" message:linkStr delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
      [alertView show];
      }
      }
      } - (void)attributedLabel:(TYAttributedLabel *)attributedLabel textStorageLongPressed:(id<TYTextStorageProtocol>)textStorage onState:(UIGestureRecognizerState)state atPoint:(CGPoint)point
      {
      NSLog(@"textStorageLongPressed");
      }
    • 上述代码中,有个 subStrUseURL 的方法,代码如下(可直接复制是使用):***本人用的是类方法,读者也可以使用对象方法***
    •  

      #pragma mark - 根据URL剪切字符串成数组
      /** 根据URL剪切数组 */
      + (NSMutableArray *)subStrUseURL:(NSString *)string
      { NSError *error; //可以识别url的正则表达式 NSString *regulaStr = @"((http[s]{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)"; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regulaStr
      options:NSRegularExpressionCaseInsensitive
      error:&error]; NSArray *arrayOfAllMatches = [regex matchesInString:string options: range:NSMakeRange(, [string length])];
      NSMutableArray *arr=[[NSMutableArray alloc]init];
      NSMutableArray *rangeArr=[[NSMutableArray alloc]init];
      for (NSTextCheckingResult *match in arrayOfAllMatches){
      NSString* substringForMatch;
      substringForMatch = [string substringWithRange:match.range];
      [arr addObject:substringForMatch]; [rangeArr addObject:[NSValue valueWithRange:match.range]];
      }
      NSString *subStr=string;
      // for (NSString *str in arr) {
      // [rangeArr addObject:[self rangesOfString:str inString:subStr]];
      // } UIFont *font = [UIFont systemFontOfSize:];
      NSMutableAttributedString *attributedText; attributedText=[[NSMutableAttributedString alloc]initWithString:subStr attributes:@{NSFontAttributeName :font}]; NSMutableArray *urlArray = [NSMutableArray array]; //把字符串根据URL剪切成数组
      NSInteger index = ;
      NSMutableArray *strArray = [[NSMutableArray alloc] init];
      for (NSInteger i = ; i < rangeArr.count; i++) {
      NSValue *value = rangeArr[i];
      NSInteger valueLoction = value.rangeValue.location;
      NSInteger valueLength = value.rangeValue.length;
      if (i == && valueLoction != ) {
      [strArray addObject:[string substringWithRange:NSMakeRange(, valueLoction)]];
      index = valueLoction;
      }
      if (index != valueLoction) {
      [strArray addObject:[string substringWithRange:NSMakeRange(index, valueLoction - index)]];
      index = index + valueLength;
      }
      [strArray addObject:[string substringWithRange:NSMakeRange(valueLoction, valueLength)]];
      index = index + valueLength;
      if (i == rangeArr.count - && (valueLoction + valueLength != string.length)) {
      [strArray addObject:[string substringWithRange:NSMakeRange(valueLength + valueLoction, string.length - valueLength - valueLoction)]];
      }
      }
      if (rangeArr.count == ) {
      [strArray addObject:string];
      }
      NSLog(@"----strArray = %@", strArray); //获取string的URL全部链接
      for(NSValue *value in rangeArr) {
      NSInteger index=[rangeArr indexOfObject:value];
      [urlArray addObject:[NSURL URLWithString:[arr objectAtIndex:index]]];
      } return strArray;
      } //获取查找字符串在母串中的NSRange
      + (NSValue *)rangesOfString:(NSString *)searchString inString:(NSString *)str {
      NSRange searchRange = NSMakeRange(, [str length]);
      NSRange range;
      if ((range = [str rangeOfString:searchString options: range:searchRange]).location != NSNotFound) {
      searchRange = NSMakeRange(NSMaxRange(range), [str length] - NSMaxRange(range));
      }
      return [NSValue valueWithRange:range];
      }
    •  UITextView的实现方法
    • . 声明一个_chatText, 在.h
      @protected
      UITextView *_chatText; .在.m中实例化,如下:
      //设置链接地址的颜色属性
      NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor blueColor],
      NSUnderlineColorAttributeName: [UIColor blueColor],
      NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)}; //创建实例化_chatText
      UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(, , , )];
      textView.backgroundColor = [UIColor clearColor];
      textView.delegate = self;
      textView.editable = NO; //设置不能编辑
      textView.contentInset = UIEdgeInsetsZero;
      textView.textContainerInset = UIEdgeInsetsZero;
      textView.scrollIndicatorInsets = UIEdgeInsetsZero;
      textView.textContainer.lineFragmentPadding = ;
      textView.textContainerInset = UIEdgeInsetsMake(, , , );
      _chatText = textView;
      _chatText.linkTextAttributes= linkAttributes; //给chatText链接属性赋值 .给chatText赋值,此处没发动态显示获取的数据,就用一个固定的值来代替:
      本人此处,后台已经将字符串切割出来返回给我们,所以,如果URL(链接)后面带有空格的话,会将空格一起返回。但是因为UITextView本身功能的局限性,无法识别链接待空格的网址,点击跳转时会跳转不过去,在代理方法中,url会返回null。因此做了如下的处理: NSString *text = @"http://baidu.com "; //注意com后面有一个空格
      if ([self.text hasPrefix:@"http"]) {
      //判断如果是http
      NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:self.text attributes:@{NSFontAttributeName : [msg textFont], NSForegroundColorAttributeName : [UIColor blueColor]}];
      NSString *str = text;
      if ([self.text hasSuffix:@" "]) {
      //尾部有空格,那么除掉尾部的空格,这个是指设置属性的时候,去掉空格,并不是在整体的数据源出掉
      str = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
      }
      [attributedString addAttribute:NSLinkAttributeName
      value:str
      range:[[attributedString string] rangeOfString:str]];
      //设置下划线
      [attributedString addAttribute:NSUnderlineStyleAttributeName
      value:[NSNumber numberWithInteger:NSUnderlineStyleSingle]
      range:[[attributedString string] rangeOfString:str]];
      _chatText.attributedText = attributedString; }else {
      NSAttributedString *str = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName : [msg textFont], NSForegroundColorAttributeName : [msg textColor]}];
      _chatText.attributedText = attributedString;
      }  .设置代理,并实现方法:
      - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange { NSLog(@"url :%@",URL);
      if ([[URL scheme] isEqualToString:@"http"]) {
      [ [ UIApplication sharedApplication] openURL:URL];
      return NO;
      }
      return YES;
      }

(UIText设置的东西略多,本人只能记录当时遇到的问题和解决方法了)

iOS 自动识别URL(链接)功能的实现的更多相关文章

  1. 小程序分享链接功能 - onShareAppMessage

    onShareAppMessage用法: 只需要在button标签中加入open-type="share",小程序ui就会自动识别分享链接功能 <button data-na ...

  2. ios系统中各种设置项的url链接

    ios系统中各种设置项的url链接 在代码中调用如下代码:NSURL*url=[NSURL URLWithString:@"prefs:root=WIFI"];[[UIApplic ...

  3. iOS解析新浪微博的@##以及URL链接并展示

    最近在做一个跟微博相关的应用.其中涉及到了对微博中@.##以及URL链接的解析与展示.分享一下个人处理的方式,希望对需要的人有所帮助. 最终的展现效果: 首先,第一步是你得从纯文本中找到它们.毫无疑问 ...

  4. iphone 上微信的“复制链接”功能复制出来的是修改前的链接

    问题描述: 在 iOS 系统中,用微信打开了 A 页面的链接,然后由 A 页面进入 B 页面 在 B 页面打开微信右上角菜单,使用“复制链接”功能 最后粘贴出来的链接是 A 页面的链接 分析原因: 这 ...

  5. ios 自定义URL Scheme 设计

    在 iOS 里,程序之间都是相互隔离,目前并没有一个有效的方式来做程序间通信,幸好 iOS 程序可以很方便的注册自己的 URL Scheme,这样就可以通过打开特定 URL 的方式来传递参数给另外一个 ...

  6. iOS之开发支付功能概述

    前言:本随笔将对IOS开发的支付功能进行一个概述. 内容大纲: 一.常见的支付方案简介 二.第三方支付SDK 三.苹果官方支付方案 四.Web支付方案 正文: 一.常见的支付方案简介 在微信支付中 微 ...

  7. IOS开发之支付功能概述

    前言:本随笔将对IOS开发的支付功能进行一个概述. 内容大纲: 一.常见的支付方案简介 二.第三方支付SDK 三.苹果官方支付方案 四.Web支付方案 正文: 一.常见的支付方案简介 在微信支付中 微 ...

  8. iOS根据Url 获取图片尺寸

    iOS根据Url 获取图片尺寸 // 根据图片url获取图片尺寸 +(CGSize)getImageSizeWithURL:(id)imageURL { NSURL* URL = nil; if([i ...

  9. 移除wordpress留言中自动链接功能

    默认情况下,在 WordPress 博客的留言中含有 URL,会自动变成可点击的,虽然这样的链接是 nofollow 的,但是还是成为 SPAM 利用的对象,所以可以移除这个自动链接功能. 我们可以在 ...

随机推荐

  1. 批量部署Hadoop集群环境(1)

    批量部署Hadoop集群环境(1) 1. 项目简介: 前言:云火的一塌糊涂,加上自大二就跟随一位教授做大数据项目,所以很早就产生了兴趣,随着知识的积累,虚拟机已经不能满足了,这次在服务器上以生产环境来 ...

  2. Redis学习笔记(六)有序集合进阶

    1.基础操作 ZCARD(获取成员数量) ZINCRBY key_name num member(将member的分数加num) ZCOUNT key_name min max(获取分数在min与ma ...

  3. 升级或者重装Discuz! 版本后 QQ互联英文乱码显示的正确解决方法

    升级Discuz! X3版本QQ互联英文乱码!connect_viewthread_share_to_qq!  目前Discuz!论坛上 最简单的解决方法: 第一步:后台----->站长---- ...

  4. CocosCreator工程内的命名

    命名结构总体的命名结构遵循以下格式 前缀-内容-尾缀 - 前缀:用来定义node的属性- 内容:node的名字- 尾缀:序列或状态1231. 前缀说明:在开始的时候定义/声明这个节点的属性前缀可以是一 ...

  5. 看Spring Data如何简化数据操作

    Spring Data 概述 Spring Data 用于简化数据库访问,支持NoSQL 和 关系数据存储,其主要目标是使数据库的访问变得方便快捷. SpringData 项目所支持 NoSQL 存储 ...

  6. vue+Java 前后端分离,多次请求Session不一致的问题(网络上找的)

    在vue main.js中增加以下配置: import axios from 'axios'; axios.defaults.withCredentials=true; 请求时:设置 withCred ...

  7. No-5.远程管理常用命令

    远程管理常用命令 目标 关机/重启 shutdown 查看或配置网卡信息 ifconfig ping 远程登录和复制文件 ssh scp 01. 关机/重启 序号 命令 对应英文 作用 01 shut ...

  8. 【分享】 封装js操作textarea 方法集合(兼容很好)。

    请使用下面的btn操作. 虽然你现在看来没什么用,当要用的时候又到处找资料,还不如现在收集一下.         在DOM里面操作textarea里面的字符,是比较麻烦的. 于是我有这个封装分享给大家 ...

  9. nginx解决跨域(前后端分离)

    Nginx解决跨域问题 后端接口 请求地址 返回数据(json数据) http://127.0.0.1:8080//app Hello World! 前端代码 通过nginx做静态资源服务器访问端口8 ...

  10. Http请求封装(对HttpClient类的进一步封装,使之调用更方便。另外,此类管理唯一的HttpClient对象,支持线程池调用,效率更高)

    package com.ad.ssp.engine.common; import java.io.IOException; import java.util.ArrayList; import jav ...