iOS开发封装一个可以响应超链接的label——基于RCLabel的交互扩展

简介:

iOS开发封装一个可以响应超链接的label——基于RCLabel的交互扩展

一、引言

        iOS系统是一个十分注重用户体验的系统,在iOS系统中,用户交互的方案也十分多,然而要在label中的某部分字体中添加交互行为确实不容易的,如果使用其他类似Button的控件来模拟,文字的排版又将是一个解决十分困难的问题。这个问题的由来是项目中的一个界面中有一些广告位标签,而这些广告位的标签却是嵌在文本中的,当用户点击文字标签的位置时,会跳转到响应的广告页。

        CoreText框架和一些第三方库可以解决这个问题,但直接使用CoreText十分复杂,第三方库多注重于富文本的排版,对类似文字超链接的支持亦不是特别简洁,我们可以借助一些第三方的东西进行针对性更强,更易用的封装。

        RCLabel是一个第三方的将html字符串进行文本布局的工具,代码十分轻巧,并且其是基于CoreText框架的,其原生性和扩展性十分强。在以前的一篇博客中,我将RCLabel进行了一些改进,使其支持异步加载远程图片,并且提供了更加简洁的面向应用的方法,博客地址如下:

扩展于RCLabel的支持异步加载网络图片的富文本引擎的设计:http://my.oschina.net/u/2340880/blog/499311 。

        本篇博文,将在其基础上,完成设计一个可以支持文本超链接的文字视图。

二、视图类与模型类的设计

        RCLabel的核心之处在于将HTML文本转换为富文本布局视图,因此我们可以将要显示的文本编程html字符串,将其可以进行用户交互的部分进行html超链接关联,RCLabel就检测到我们点击的区域进行响应逻辑的回调。设计类如下:

.h文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//文本与超链接地址关联的model类 后面会说
@ class  YHBaseLinkingLabelModel;
 
@protocol YHBaseLinkingLabelProtocol <NSObject>
 
@optional
/**
  *点击超链接后出发的代理方法 model中有链接地址和文字
  */
-( void )YHBaseLinkingLabelClickLinking:(YHBaseLinkingLabelModel *)model;
/**
  *尺寸改变后出发的方法
  */
-( void )YHBaseLinkingLabelSizeChange:(CGSize)size;
@end
 
@interface YHBaseLinkingLabel : YHBaseView
/**
  *文字数组 里面存放这文字对应的超链接对象
  */
@property(nonatomic,strong)NSArray<YHBaseLinkingLabelModel *> * textArray;
@property(nonatomic,weak)id<YHBaseLinkingLabelProtocol>delegate;
/**
  *设置文字颜色
  */
@property(nonatomic,strong)UIColor * textColor;
/**
  *设置超链接文字颜色
  */
@property(nonatomic,strong)UIColor * linkColor;
/**
  *设置字体大小
  */
@property(nonatomic,assign)NSUInteger fontSize;
/**
  *设置超链接字体大小
  */
@property(nonatomic,assign) int  linkingFontSize;
/**
  *设置是否显示下划线
  */
@property(nonatomic,assign) BOOL  isShowUnderLine;
@end

.m文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
@interface YHBaseLinkingLabel()<YHBaseHtmlViewProcotop>
@end
 
@implementation YHBaseLinkingLabel
{
     //以前博客中 封装的显示HTML字符串富文本的视图
     YHBaseHtmlView * _label;
}
/*
// 重载一些初始化方法
- (instancetype)init
{
     self = [super init];
     if  (self) {
         _label = [[YHBaseHtmlView alloc]init];
         [self addSubview:_label];
         [_label mas_makeConstraints:^(MASConstraintMaker *make) {
             make.leading.equalTo(@0);
             make.trailing.equalTo(@0);
             make.top.equalTo(@0);
             make.bottom.equalTo(@0);
         }];
          _label.delegate=self;
     }
     return  self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
     self = [super initWithCoder:coder];
     if  (self) {
         _label = [[YHBaseHtmlView alloc]init];
         [self addSubview:_label];
         [_label mas_makeConstraints:^(MASConstraintMaker *make) {
             make.leading.equalTo(@0);
             make.trailing.equalTo(@0);
             make.top.equalTo(@0);
             make.bottom.equalTo(@0);
         }];
          _label.delegate=self;
     }
     return  self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
     self = [super initWithFrame:frame];
     if  (self) {
         _label = [[YHBaseHtmlView alloc]init];
         [self addSubview:_label];
         [_label mas_makeConstraints:^(MASConstraintMaker *make) {
             make.leading.equalTo(@0);
             make.trailing.equalTo(@0);
             make.top.equalTo(@0);
             make.bottom.equalTo(@0);
         }];
         _label.delegate=self;
     }
     return  self;
}
//设置文本数组
-( void )setTextArray:(NSArray<YHBaseLinkingLabelModel *> *)textArray{
     _textArray = textArray;
     //进行html转换
     NSString * htmlString = [self transLinkingDataToHtmlStr:textArray];
     //进行布局
     [_label reSetHtmlStr:htmlString];
     
}
-( void )setTextColor:(UIColor *)textColor{
     _textColor = textColor;
     _label.fontColor = textColor;
}
-( void )setLinkColor:(UIColor *)linkColor{
     _linkColor = linkColor;
     _label.linkingColor = linkColor;
}
-( void )setFontSize:(NSUInteger)fontSize{
     _fontSize = fontSize;
     [_label setFontSize:( int )fontSize];
}
-( void )setLinkingFontSize:( int )linkingFontSize{
     _linkingFontSize = linkingFontSize;
     [_label setLinkingSize:linkingFontSize];
}
-( void )setIsShowUnderLine:( BOOL )isShowUnderLine{
     _isShowUnderLine = isShowUnderLine;
     [_label setShowUnderLine:isShowUnderLine];
}
-(NSString *)transLinkingDataToHtmlStr:(NSArray<YHBaseLinkingLabelModel *> *)data{
     NSMutableString * mutStr = [[NSMutableString alloc]init];
     for  ( int  i=0; i<data.count; i++) {
     //这个model中存放的是超链接部分的文字和对应的url
         YHBaseLinkingLabelModel * model = data[i];
         if  (!model.linking) {
             [mutStr appendString:model.text];
         } else  {
             [mutStr appendString:@ "<a href=" ];
             [mutStr appendString:model.linking];
             [mutStr appendString:@ ">" ];
             [mutStr appendString:model.text];
             [mutStr appendString:@ "</a>" ];
         }
     }
     return  mutStr;
}
 
#pragma mark delegate
//点击的回调
-( void )YHBaseHtmlView:(YHBaseHtmlView *)htmlView ClickLink:(NSString *)url{
     for  (YHBaseLinkingLabelModel * model in _textArray) {
         if  ([model.linking isEqualToString:url]) {
             if  ([self.delegate respondsToSelector:@selector(YHBaseLinkingLabelClickLinking:)]) {
                 [self.delegate YHBaseLinkingLabelClickLinking:model];
                 return ;
             }
         }
     }
}
//布局尺寸改变的回调
-( void )YHBaseHtmlView:(YHBaseHtmlView *)htmlView SizeChanged:(CGSize)size{
     if  ([self.delegate respondsToSelector:@selector(YHBaseLinkingLabelSizeChange:)]) {
         [self.delegate YHBaseLinkingLabelSizeChange:size];
     }
}
@end

上面我们有用到一个YHBaseLinkingLabelModel类,这个类进行了链接与字符的映射,设计如下:

?
1
2
3
4
5
6
7
8
9
10
11
@interface YHBaseLinkingLabelModel : YHBaseModel
/**
  *文字内容
  */
@property(nonatomic,strong)NSString * text;
/**
  *超链接地址 nil则为无
  */
@property(nonatomic,strong)NSString * linking;
 
@end

        YHBaseHtmlView类是对RCLabel的一层封装,其中也对RCLabel进行了一些优化和改动,代码较多且在上篇博客中有介绍,这里不再多做解释了。

        在ViewController中写如下代码进行使用:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
- ( void )viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view, typically from a nib.
    YHBaseLinkingLabel * label = [[YHBaseLinkingLabel alloc]initWithFrame:CGRectMake(100, 100, 200, 100)];
     NSMutableArray * array = [[NSMutableArray alloc]init];
     for  ( int  i=0; i<6; i++) {
         YHBaseLinkingLabelModel * model = [[YHBaseLinkingLabelModel alloc]init];
         if  (!(i%2)) {
             model.text =[NSString stringWithFormat:@ "第%d个标签" ,i];
             model.linking = [NSString stringWithFormat:@ "第%d个标签" ,i];
         } else {
             model.text = @ ",不能点得文字," ;
         }
         [array addObject:model];
     }
     label.textColor = [UIColor blackColor];
     label.linkColor = [UIColor purpleColor];
     label.fontSize = 15;
     label.linkingFontSize = 17;
     label.isShowUnderLine=YES;
     label.delegate=self;
     label.textArray = array;
     [self.view addSubview:label];
    
}
-( void )YHBaseLinkingLabelClickLinking:(YHBaseLinkingLabelModel *)model{
     NSLog(@ "%@" ,model.linking);
}

运行效果如下:

224957_KSL8_2340880.png

效果不错,并且十分简单易用,对吧。

目录
相关文章
|
6天前
|
IDE Android开发 iOS开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
【9月更文挑战第27天】在移动应用开发的世界中,Android和iOS是两个主要的操作系统平台。每个系统都有其独特的开发环境、工具和用户群体。本文将深入探讨这两个平台的关键差异点,并分析这些差异如何影响应用的性能、用户体验和最终的市场表现。通过对比分析,我们将揭示选择正确的开发平台对于确保项目成功的重要作用。
|
2天前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
18 7
|
6天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台解决方案
【9月更文挑战第27天】在移动应用开发的广阔天地中,安卓和iOS两大操作系统如同双子星座般耀眼。开发者们在这两大平台上追逐着创新的梦想,却也面临着选择的难题。如何在保持高效的同时,实现跨平台的开发?本文将带你探索跨平台开发的魅力所在,揭示其背后的技术原理,并通过实际案例展示其应用场景。无论你是安卓的忠实拥趸,还是iOS的狂热粉丝,这篇文章都将为你打开一扇通往跨平台开发新世界的大门。
|
6天前
|
iOS开发 Python
6-8|如何使用Python语言开发IOS混淆工具
6-8|如何使用Python语言开发IOS混淆工具
|
物联网 Android开发 iOS开发
iOS开发 - 蓝牙学习的总结
iOS开发 - 蓝牙学习的总结
171 0
|
iOS开发
IOS开发---菜鸟学习之路--(九)-利用PullingRefreshTableView实现下拉刷新
本章主要讲解如何利用PullingRefreshTableView实现下拉(上拉)刷新的操作  PullingRefreshTableView 实现上下拉刷新的例子百度有很多,大家可以自己搜索下,先看下那些例子(一般搜索过来的都是一样的大家反正先把那部分内容先了解一下,然后再看本文档比较好。
878 0
|
iOS开发 Android开发 存储
IOS开发---菜鸟学习之路--(十)-实现新闻详细信息浏览页面
前面已经将了上下拉刷新 实现了上下拉刷新后我们的第一级界面就做好,接下来我们就需要实现 新闻详细信息浏览了 我个人认为一般实现新闻详细页面的方法有两种(主要是数据源的不同导致了方法的不同) 第一种是本身新闻就是一个链接地址,同时是已经处理好的适应手机浏览的网页 对于这种类型的数据源,我们直接在页面中放一个WebView控件,然后将URL传递过去就好了 另一种则是普通的包含标题、时间、内容、图片等数据结构的新闻内容(我们要实现的也是这种新闻,因为实现了这种之后, 我们就可以实现任何自定义的详细信息的页面了。
875 0
|
iOS开发
IOS开发---菜鸟学习之路--(十一)-使新闻内容自适应高度
上一章当中,我们留了一个小BUG。 其实就是浏览新闻的时候,如果文字内容过长的花,UITextView 会有个下拉框,而最底层的UIScrollView也有个下拉框,那么在使用的时候就会非常的不爽。 而这章呢我们就要解决这样一个问题了 其实并不是很复杂的修改方法 我们只需要将viewDidL...
896 0
|
iOS开发
IOS开发---菜鸟学习之路--(十二)-利用ASIHTTPRequest进行异步获取数据
想要实现异步获取的话我这边了解过来有两个非常简单的方式 一个是利用ASIHTTPRequest来实现异步获取数据 另一个则是利用MBProgressHUD来实现异步获取数据 本章就先来讲解如何利用ASIHTTPRequest类来实现异步数据获取 首先大家需要百度一下ASIHTTPRequest 然后看一下百度里搜到的那些文章(不要问具体是那篇,因为我发现百度搜过来的东西全部都是一样的,所以。
1003 0
|
iOS开发
IOS开发---菜鸟学习之路--(十三)-利用MBProgressHUD进行异步获取数据
本章将介绍如何利用MBProgressHUD实现异步处理数据。 其实我本来只是像实现一个加载数据时提示框的效果,然后问了学长知道了这个类,然后就使用了 接着就发现了一个“BUG” 再然后就发现原来MBProgressHUD处理数据的时候是异步处理的 而所谓的“BUG”其实是在我实现了ASIFormDataRequest 异步处理数据后 又利用MBProgressHUD来显示加载数据框所导致的。
1070 0