你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS App開辟中擴大RCLabel組件停止基於HTML的文本結構

iOS App開辟中擴大RCLabel組件停止基於HTML的文本結構

編輯:IOS開發綜合

IOS體系是一個非常重視用戶體驗的體系,在IOS體系中,用戶交互的計劃也非常多,但是要在label中的某部門字體中添加交互行動確切不輕易的,假如應用其他相似Button的控件來模仿,文字的排版又將是一個處理好不容易的成績。這個成績的由來是項目中的一個界面中有一些告白位標簽,而這些告白位的標簽倒是嵌在文本中的,當用戶點擊文字標簽的地位時,會跳轉到呼應的告白頁。
CoreText框架和一些第三方庫可以處理這個成績,但直接應用CoreText非常龐雜,第三方庫多重視於富文本的排版,對相似文字超鏈接的支撐亦不是特殊簡練,我們可以借助一些第三方的器械停止針對性更強,更容易用的封裝。
RCLabel是一個第三方的將html字符串停止文本結構的對象,代碼非常輕盈,而且其是基於CoreText框架的,其原素性和擴大性非常強。

1、擴大於RCLabel的支撐異步加載收集圖片的富文本引擎的設計
在IOS開辟中,圖文混排一向都是UI編程的一個焦點點,也有很多優良的第三方引擎,個中很著名的一套圖文混排的框架叫做DTCoreText。然則在前些日的做的一個項目中,我並沒有采取這套框架,緣由有二,一是這套框架體積異常年夜,而項目標需求其實其實不太高;二是要在這套框架中修正一些器械,難度也異常年夜,我終究采取的是一個叫做RCLabel的第三方控件,經由一些簡略的優化和完美,到達了項目標請求。
先來引見一下我項目中的圖文混排的需求:起首我從辦事器中取到的數據是字符串,然則個中交叉圖片的地位是一個HTML的圖片標簽,標簽裡的資本途徑就是圖片的要求地址。須要到達的請求是這些數據顯示出來後,圖片的地位要空出來,然後經由過程異步的收集要求獲得圖片的數據,再將圖片拔出文字中。
要本身完成一套如許的引擎確切會比擬費事,榮幸的是RCLabel可以完善的幫我們解析帶有HTML標簽的數據,停止圖文混排,我們先來看一下這個器械怎樣用,上面是我封裝的一個展現html數據的view:
@interface YHBaseHtmlView()<YHRTLabelImageDelegate>
{
    //RCLabel對象
    RCLabel * _rcLabel;
    //保留屬性 用於異步加載完成後刷新
    RTLabelComponentsStructure * _origenComponent;
    //含html標簽的數據字符串
    NSString * _srt;
}
@end
@implementation YHBaseHtmlView
/*
// Only override drawRect: if you perform custom draWing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // DraWing code
}
*/
- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
    //將rclabel初始化
        _rcLabel = [[RCLabel alloc]init];
        [self addSubview:_rcLabel];
    }
    return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _rcLabel = [[RCLabel alloc]initWithFrame:frame];
        [self addSubview:_rcLabel];
    }
    return self;
}
-(void)reSetHtmlStr:(NSString *)htmlStr{
    _srt = htmlStr;
    //這個署理是我額定添加的 前面說明
    _rcLabel.imageDelegate=self;
    //設置frame
    _rcLabel.frame=CGRectMake(0, 0, self.frame.size.width, 0);
    //設置屬性
    _origenComponent = [RCLabel extractTextStyle:htmlStr IsLocation:NO withRCLabel:_rcLabel];
    _rcLabel.componentsAndPlainText = _origenComponent;
   //獲得排版後的size
    CGSize size = [_rcLabel optimumSize];
    //從新設置frame
    _rcLabel.frame=CGRectMake(0, 0, _rcLabel.frame.size.width, size.height);
    self.frame=CGRectMake(self.frame.origin.x, self.frame.origin.y, _rcLabel.frame.size.width, size.height);
}
//這是我額定添加的署理辦法的完成
-(void)YHRTLabelImageSuccess:(RCLabel *)label{
    _origenComponent = [RCLabel extractTextStyle:_srt IsLocation:NO withRCLabel:_rcLabel];
    _rcLabel.componentsAndPlainText = _origenComponent;
   
    CGSize size = [_rcLabel optimumSize];
    _rcLabel.frame=CGRectMake(0, 0, _rcLabel.frame.size.width, size.height);
    self.frame=_rcLabel.frame;
    if ([self.delegate respondsToSelector:@selector(YHBaseHtmlView:SizeChanged:)]) {
        [self.delegate YHBaseHtmlView:self SizeChanged:self.frame.size];
    }
}
RCLabel的用法很簡略,總結來講只要三步:
1.初始化並設置frame
2.經由過程帶html標簽的數據停止屬性的初始化
3.將屬性停止set設置偏重設視圖frame
RCLabel是很壯大,而且代碼很簡潔,然則個中處置圖片的部門必需是當地的圖片,即圖片html標簽中的途徑必需是當地圖片的名字,其外部是經由過程[UIImage ImageNamed:]這個辦法停止圖片的襯著的,所以要到達我們的須要,我們須要對其停止一些簡略的擴大:
1、在屬性設置辦法中添加一個參數,來辨別當地圖片與收集圖片:
//我在這個辦法中添加了location這個bool值,現實上rclabel這個參數也是我添加的,是為了前面署理應用的
+ (RTLabelComponentsStructure*)extractTextStyle:(NSString*)dataimage IsLocation:(BOOL)location withRCLabel:(RCLabel *)rcLabel;
2、在完成辦法中添加以下代碼,由於原文件有1900多行,在個中弄清晰邏輯關系也確切費了我不小的力量,我這裡只將我添加的代碼貼過去
#warning 這裡停止了兼容性處置
                if (location) {
                //當地圖片的襯著
                    if (tempURL) {
                        UIImage  *tempImg = [UIImage imageNamed:tempURL];
                        component.img = tempImg;
                       
                    }
                }else{//這裡做長途圖片數據的處置
                //這裡我停止了緩存的操作,這個緩存中間是我封裝的框架中的另外一套器械,這裡可以不消在乎
                    //先讀緩存
                    NSData * ceche = [[YHBaseCecheCenter sharedTheSingletion] readCecheFile:tempURL fromPath:YHBaseCecheImage];
                    if (ceche) {
                        UIImage * tempImg = [UIImage imageWithData:ceche];
                        component.img=tempImg;
                    }else{
                    //在分線程中停止圖片數據的獲得
                        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
                            if (tempURL) {
                                NSData * data = [YHBaseData getDataWithUrl:tempURL];
                                if (data) {
                                //獲得完成後村緩存
                                    //做緩存
                                    [[YHBaseCecheCenter sharedTheSingletion]writeCecheFile:data withFileID:tempURL toPath:YHBaseCecheImage];
                                    //賦值 回調署理
                                    UIImage * tempImg = [UIImage imageWithData:data];
                                    component.img=tempImg;
                                    //這裡署理是我添加的,當圖片下載完成後 告訴視圖從新排版
                                    if ([[rcLabel imageDelegate]respondsToSelector:@selector(YHRTLabelImageSuccess:)]) {
                                        //在主線程中履行回調
                                        //這個處所要在主線程中履行,不然刷新會有延時
                                        dispatch_async(dispatch_get_main_queue(), ^{
                                             [[rcLabel imageDelegate] YHRTLabelImageSuccess:rcLabel];
                                        });
                           
                                    }
                                  
                                }
                               
                            };
                           
                        });
                    }                
                   
                }

2、視圖類與模子類的設計
RCLabel的焦點的地方在於將HTML文本轉換為富文本結構視圖,是以我們可以將要顯示的文本編程html字符串,將其可以停止用戶交互的部門停止html超鏈接聯系關系,RCLabel就檢測到我們點擊的區域停止呼應邏輯的回調。設計類以下:
.h文件
//文本與超鏈接地址聯系關系的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文件
@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類,這個類停止了鏈接與字符的映照,設計以下:
@interface YHBaseLinkingLabelModel : YHBaseModel
/**
 *文字內容
 */
@property(nonatomic,strong)NSString * text;
/**
 *超鏈接地址 nil則為無
 */
@property(nonatomic,strong)NSString * linking;
@end
YHBaseHtmlView類是對RCLabel的一層封裝,個中也對RCLabel停止了一些優化和修改,代碼較多且在上篇博客中有引見,這裡不再多做說明了。
在ViewController中寫以下代碼停止應用:
- (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);
}
運轉後果以下:

201671291423648.jpg (825×575)

後果不錯,而且非常簡略易用,對吧。

【iOS App開辟中擴大RCLabel組件停止基於HTML的文本結構】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved