UITableViewCell 加載 HTML 代碼

需求如下:


需求.jpeg

【生效時間】和【辦理號碼】的高度可以計算后频。
【圖文介紹】返回的是一串 HTML 代碼沼撕,類似 "<span style="font-size:14px;color:#000000;">\U3010\U8d44\U8d39\U6807\U51c6\U3011</span><br />" 這樣的代碼遭顶。
加載 HTML 代碼,可用 UILabel 或者 UIWebView牛柒,難點在于對高度的計算堪簿。

UILabel 加載 HTML

label 加載 HTML 的原理是把HTML轉(zhuǎn)成富文本,在賦值給
label.attributedText
HTML 轉(zhuǎn)富文本的代碼如下:

    NSDictionary *options = @{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
                               NSCharacterEncodingDocumentAttribute :@(NSUTF8StringEncoding) };
    
    // htmlString 為需加載的HTML代碼
    NSData *data = [htmlString dataUsingEncoding:NSUTF8StringEncoding];
    
    _label.attributedText = [[NSAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil];

此時可計算出文本高度皮壁,代碼如下:

CGFloat attriHeight = [_label.attributedText boundingRectWithSize:CGSizeMake(SCREEN_WIDTH - 30*layoutBy6(), CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size.height;

可用類方法返回Cell的高度

// cell的高度
+(CGFloat)getCellHeight:(NSString*)htmlStr {
    
    NSDictionary *options = @{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
                               NSCharacterEncodingDocumentAttribute :@(NSUTF8StringEncoding)
                               };
    NSData *data = [htmlStr dataUsingEncoding:NSUTF8StringEncoding];
    NSAttributedString *attrStr =  [[NSAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil];

    CGFloat attriHeight = [attrStr boundingRectWithSize:CGSizeMake([UIScreen mainScreen].bounds.size.width - 30, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size.height;
    
    return attriHeight ;
}

加載出來的效果如下:


UILabel加載效果.png
UIWebView 加載 HTML

UIWebView 加載 HTML 的方法很簡單椭更,就一句代碼

[_webView loadHTMLString:desStr baseURL:nil];

但此時并不知道 webView 的高度,需要通過 UIWebViewDelegate 的代理方法獲取高度蛾魄。

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    CGFloat webViewHeight = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] floatValue];
    _webView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, webViewHeight);
}

由于高度必須在 webView 完成加載之后才能獲取得到虑瀑,當獲取到高度之后湿滓,需要通知 tableView reloadData。然而舌狗,tableView 刷新會對該 Cell 重新賦值叽奥,Cell 賦值導致 webView 又完成一遍加載。痛侍。朝氓。程序陷入了死循環(huán)。
避免該情況主届,對需要加載的內(nèi)容提前賦值給 Cell赵哲。不要在tableview cellForRowAtIndexPath 方法里賦值,網(wǎng)絡(luò)請求回來后就賦值君丁。把 webViewCell 懶加載枫夺,Block 里面執(zhí)行 tableView section 更新。

Cell 的代碼如下??

@interface WebViewCell : UITableViewCell
<UIWebViewDelegate>

@property (nonatomic , copy) NSString *webContentStr; 

@property (nonatomic , assign) CGFloat cellHeight;  

@property (nonatomic, copy) void(^Block)(void);   // Block回調(diào)

@end

@implementation WebViewCell

#pragma mark setter
-(void)setWebContentStr:(NSString *)webContentStr {
    _webContentStr = webContentStr;
    // 移除所有視圖
    [self.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    // 創(chuàng)建 WebView 谈截,webView 須給初始值筷屡,在 delegate 再更改 frame
    UIWebView *webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 1)];
    webView.scrollView.scrollEnabled = NO;
    webView.delegate =self;
    [webView sizeToFit];
    [self.contentView addSubview:webView];
    //加載Html文件
    [webView loadHTMLString:desStr baseURL:nil];
}

#pragma mark UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    //加載完成后獲取WebView實際高度
    CGFloat webViewHeight = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] floatValue];
    webView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, webViewHeight);
    
    self.cellHeight = webViewHeight;
    if (self.Block) {
        self.Block();
    }
}

@end

VC 部分的代碼??

@property (nonatomic, strong) WebViewCell *webCell涧偷;


#pragma mark net request
- (void)gainWebContent {
  self.webCell.webContentStr = 網(wǎng)絡(luò)請求回來的數(shù)據(jù)簸喂;
}

#pragma mark tableView
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return self.webCell.cellHeight;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 2) {
        return self.webCell;
    }
}

#pragma mark lazy load
- (WebCell *)webCell{
    if (!_webCell) {
        NSString *cellIdentifier = @"webCell";
         _webCell = [[WebCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        //回調(diào)刷新Cell內(nèi)容及高度
        __weak typeof(self) weakSelf = self;
        _webCell.Block = ^{
            __strong typeof(self) strongSelf = weakSelf;
            [strongSelf.tableView reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationNone];
        };
    }
    return _webCell;
}
題外話

@"document.body.scrollHeight" 中的 scrollHeight。有的資料里面燎潮,這里的語句是 @"document.body.offsetHeight"喻鳄。稍微查了一下 offsetHeight 和 scrollHeight 的區(qū)別:

1)document.documentElement.scrollHeight = document.documentElement.offsetHeight => 就是整個網(wǎng)頁文檔body的高度,隨著網(wǎng)頁內(nèi)容的多少變化确封,包括網(wǎng)頁內(nèi)的所有border,margin,padding除呵;

2)body.clientHeight = body.offsetHeight => body的內(nèi)容高度,不包括margin和border值爪喘,實際上就是body的height值颜曾;

3)body.scrollHeight => 包括body的margin,body值
a 當網(wǎng)頁內(nèi)容超出瀏覽器可視窗口高度值時秉剑,= body.clientHeight+margin+border = document.documentElement.scrollHeight ;
b 當網(wǎng)頁內(nèi)容較少未超出時泛豪,= document.documentElement.clientHeigh 也就是瀏覽器窗口高度值(這是它的最小值);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末侦鹏,一起剝皮案震驚了整個濱河市诡曙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌略水,老刑警劉巖价卤,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異渊涝,居然都是意外死亡慎璧,警方通過查閱死者的電腦和手機床嫌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胸私,“玉大人既鞠,你說我怎么就攤上這事「俏模” “怎么了嘱蛋?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長五续。 經(jīng)常有香客問我洒敏,道長,這世上最難降的妖魔是什么疙驾? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任凶伙,我火速辦了婚禮,結(jié)果婚禮上它碎,老公的妹妹穿的比我還像新娘函荣。我一直安慰自己,他們只是感情好扳肛,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布傻挂。 她就那樣靜靜地躺著,像睡著了一般挖息。 火紅的嫁衣襯著肌膚如雪金拒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天套腹,我揣著相機與錄音绪抛,去河邊找鬼。 笑死电禀,一個胖子當著我的面吹牛幢码,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播尖飞,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼症副,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了葫松?” 一聲冷哼從身側(cè)響起瓦糕,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腋么,沒想到半個月后咕娄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡珊擂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年圣勒,在試婚紗的時候發(fā)現(xiàn)自己被綠了费变。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡圣贸,死狀恐怖挚歧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吁峻,我是刑警寧澤滑负,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站用含,受9級特大地震影響矮慕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜啄骇,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一痴鳄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧缸夹,春花似錦痪寻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至趟妥,卻和暖如春猫态,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背披摄。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勇凭,地道東北人疚膊。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像虾标,于是被迫代替她去往敵國和親寓盗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354