1. 程式人生 > >UITableviewCell使用以及自定義高度

UITableviewCell使用以及自定義高度

UITableView號稱是 ios裡面最難使用也是最複雜的一個控制元件?

是不是暫且不說,反正我覺得HttpRequest也是挺複雜的。

但確實被UItableview折磨了一段時間,還好搞定了一小半。

一、如何重用UITableviewCell

 重用的目的是為了減少記憶體消耗,假如有1千個cell,如果不重用,那麼每一次滑動都得重新

alloc 很多很多的cell,耗費記憶體,同時螢幕會出現不連續的現象,晃眼睛。

重用cell很簡單,在建立cell的時候,使用

alloc initwithtableviewCellStyle:reuseIdentifer這個介面建立cell例項,而非使用alloc initwithFrame

使用前者表示該cell可重用,identifer使用一個固定的NSString即可

       程式碼如下:

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];//首先從可重用佇列裡面彈出一個cell
    if (cell == nil) {//說明可重用佇列裡面並cell,此時需要重新建立cell例項,採用下面方法
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;  
    }else{//此時表示有可重用cell,直接返回即可
        NSLog(@"cell 重用啦");
    }    
	return cell;
}

二、如何如何動態調整cell的高度?

這個問題還是比較頭疼的,下面這個函式肯定要用到

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

經過實踐之後發現,可以在建立cell或者重用cell的時候,設定其frame

比如cell.frame=CGRectMake(0,0,320,450);

這個程式碼會有效,同時在下面這個函式裡面

 使用:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
  
    NSLog(@"當前是第%ld行",(long)indexPath.row);
    
    UITableViewCell *myCell=[self tableView:tableView cellForRowAtIndexPath:indexPath];//獲取當前indexPath中的cell例項
    if( myCell == nil ){
        return 0;
        
    }else{
        
        NSLog(@"%f",myCell.frame.size.height);
        return  myCell.frame.size.height;
        
    }
    return 0;
    
}
上面獲取當前indexPath的cell例項會重新申請建立一個例項(意思是個cell實際要建立兩個例項)

這樣的目的是為了獲取cell的frame,如果不這樣做也可以在第一部分建立cell的時候,將cell的frame儲存在一個私有

變數中,在heightForRowAtIndexPath中訪問這個私有變數

通過上述方式可以動態改變UITableViewCell的高度


三、對於一個UILabel,根據其內容計算CGRect

首先要設定UILable的font,比如

tmLabel.font=[UIFont  systemFontOfSize:14.0f];

然後使用boundingRectOfSize計算出該尺寸對應的矩形大小,程式碼如下:

        NSDictionary *[email protected]{NSFontAttributeName:[UIFont systemFontOfSize:12.0f]};
        CGSize labelSize=[text boundingRectWithSize:CGSizeMake(320, 990)
                                            options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
                                         attributes:attrDic context:nil].size;
        
        CGRect labelRect=CGRectMake(0, 0, labelSize.width, labelSize.height);

現在UILable的rect都可以被計算出來了,那麼如果自定義一個UITableViewCell,並且其內部的UILabel高度可變的話

也是可以實現的


四、內部含有可變高度的UILabel的UITableViewCell

如果還有其他控制元件,比如UIButton等等,也是一樣的。

這些控制元件在例項化的時候,設定frame為CGRectZero, 然後分別計算各自的高度和尺寸

使用cell.contentview addSubview 的方式,將這些子空間新增到cell中。重新計算cell的frame時

也需要把這些控制元件的frame累加上。上程式碼:

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
        
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
        label.tag = 1;
        label.lineBreakMode = NSLineBreakByCharWrapping;
        label.highlightedTextColor = [UIColor whiteColor];
        label.numberOfLines = 0;
        label.opaque = NO; // 選中Opaque表示檢視後面的任何內容都不應該繪製
        label.font=[UIFont systemFontOfSize:12.0f];
        label.backgroundColor = [UIColor grayColor];
        [cell.contentView addSubview:label];
        
        UIButton *tmpButton=[[UIButton alloc]initWithFrame:CGRectZero];
        tmpButton.tag=2;
        tmpButton.backgroundColor=[UIColor cyanColor];
        [cell.contentView addSubview:tmpButton];
        tmpButton.opaque=NO;
        [tmpButton setTitle:@"nihao" forState:UIControlStateNormal];
        [tmpButton setTitleColor:[UIColor whiteColor ]forState:UIControlStateHighlighted];
        [tmpButton addTarget:self action:@selector(tmpButtonHandler:) forControlEvents:UIControlEventTouchUpInside];
        
    }else{
        NSLog(@"cell 重用啦");
    }
    
        UILabel *tmpLabel=(UILabel *)[cell viewWithTag:1];
        NSString *text=[tmpArray objectAtIndex:indexPath.row];
        tmpLabel.text=text;
        
        UIButton *tmpButton=(UIButton *)[cell viewWithTag:2];
        
        NSDictionary *[email protected]{NSFontAttributeName:[UIFont systemFontOfSize:12.0f]};
        CGSize labelSize=[text boundingRectWithSize:CGSizeMake(320, 990)
                                            options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
                                         attributes:attrDic context:nil].size;
        
        CGRect labelRect=CGRectMake(0, 0, labelSize.width, labelSize.height);//計算UILabel的rect
        [tmpLabel setFrame:labelRect];
        [tmpButton setFrame:CGRectMake(0, labelSize.height+1, 100, 50)];//計算UIButton 子控制元件的rect
        [cell setFrame:CGRectMake(0, 0, labelSize.width, labelSize.height+50+1)];//cell的frame是以上兩個子控制元件之和
  
    return cell;
}

為何不再建立時設定frame,而是在if和else邏輯後面?

重用cell的時候,從重用cell佇列裡面取出的cell,其內容(UILabel)是之前的cell內容,需要重新填充UILabel並且重新計算

整個cell的frame並設定其frame。而建立cell的時候也需要設定frame,所以這兩個邏輯重複,直接放在if else邏輯外面做。

下面是動態改變UITableViewCell的高度圖:



相關推薦

UITableviewCell使用以及定義高度

UITableView號稱是 ios裡面最難使用也是最複雜的一個控制元件? 是不是暫且不說,反正我覺得HttpRequest也是挺複雜的。 但確實被UItableview折磨了一段時間,還好搞定了一小半。 一、如何重用UITableviewCell  重用的目的是為了減

Zabbix的通知功能以及定義腳本告警

edi web管理 har idt cti 遠程 rip 9.png ble 本節內容: Zabbix的通知功能 定義接收告警的用戶 定義Action Zabbix自定義腳本發送報警郵件 一、Zabbix的通知功能 在配置好監控項和觸發器之後,一旦正常工作中的某觸發

Android Studio 默認keystore 以及定義keystore

font upper 不能 use src lis con 位置 sha1 我們使用Android Studio 運行或測試我們的app 它使用一個默認的debug.keystore進行簽名。 這個默認簽名(keystore)是不需要密碼的,它的默認位置在 $HOME/

定義高度寬度縮小圖片

path java clas thumbnail getparent pos 比例 縮放 subst 直接上代碼: package com.henu.test; import java.awt.Graphics; import java.awt.image.Buffer

vue Element-ui 表格帶篩選框定義高度

image n-k pre chrome code lac 分享 sso spa el-table中可以在一行的某列進行篩選,代碼如下: <el-table-column prop="classOfTest" class="test" label="測試類名" :

事件監聽和window.history以及定義創建事件

lac 瀏覽器 捕獲 tps details push AD his listener 1.事件監聽window.addEventListener方法: Window.addEventListener(event, function, useCapture); useC

監控服務器cpu、磁盤、模板以及定義key

local owa pki 監控cpu 自動 parameter 發現 整形 spa 一、檢測主機存活 net.tcp.service.perf[tcp,,10050] Float型 返回0代表端口掛了 zabbix fping要開啟sudo權限之類比較不方便

cookie和session以及定義分頁

cookie值 無法 解析 link try render 強制 raise 需求 cookie Cookie的由來 大家都知道HTTP協議是無狀態的。 無狀態的意思是每次請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求都無直接關系,它不會受前面的請求響應情況直

Retrofit 2.0基於OKHttp更高效更快的網絡框架 以及定義轉換器

讀取數據 index gson final resp adapter oid 簡單的 build 時間關系,本文就 Retrofit 2.0的簡單使用 做講解 至於原理以後有空再去分析 項目全面、簡單、易懂 地址: 關於Retrofit 2.0的簡單使用如下: htt

Android Studio 預設keystore 以及定義keystore使用

我們使用Android Studio 執行或測試我們的app  它使用一個預設的debug.keystore進行簽名。 這個預設簽名(keystore)是不需要密碼的,它的預設位置在 $HOME/.android/debug.keystore,如果不存在Android s

Spring Boot 常用配置以及定義配置

原文地址:https://renguangli.com/articles/spring-boot-config Spring Boot 常用配置簡單介紹及使用 多環境配置 Spring Boot Profile 在 Spring Boot 中多環境配置檔名需要滿足 app

Java IO流中的異常處理以及定義異常例項

文章目錄 異常 自定義異常例項 finally中特殊情況例項 異常 1、 Throwable類  a) 嚴重問題:Error,比如說記憶體不夠,一般程式中不進

spring 容器的帶事件以及 定義事件

ApplicationEvent spring 的事件是為bean與bean 之間的訊息通訊提供了支援,當一個bean 處理完一個任務後,希望另外一個bean 知道並能夠做出相應的處理,這時需要另外一個bean監聽當前bean 所傳送的事件。 ApplicationEvent以及Li

微信小程式poster封面閃逝以及定義播放按鈕

小程式中poster封面閃消失,以及用圖片自定義播放按鈕,注意下面是以元件的形式來寫非頁面如下: wxml: <view > <video id='myvedio' bindended="endvedio" style="width: 100%;height=400px;

kafka模擬生產者-消費者以及定義分割槽

基本概念 kafka中的重要角色   broker:一臺kafka伺服器就是一個broker,一個叢集可有多個broker,一個broker可以容納多個topic   topic:可以理解為一個訊息佇列的名字   partition:分割槽,為了實現擴充套件性,一個topic可以分佈到多

Spring Boot Configuration 配置檔案讀取以及定義配置檔案

新增configuration  maven依賴 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configurati

在ubuntu16.04中安裝apache2+modsecurity以及定義WAF規則詳解

一、Modsecurity規則語法示例 SecRule是ModSecurity主要的指令,用於建立安全規則。其基本語法如下: SecRule VARIABLES OPERATOR [ACTIONS] VARIABLES 代表HTTP包中的標識項,規定了安全規則針對的物件。常見的

我win專案中遇到的安裝以及定義快捷方式及快捷鍵的實現方法

首先我的需求是: 1、能自動安裝 2、桌面上有快捷方式,並且有快捷鍵,打快捷鍵能自動開啟程式執行 在開發中VS2010自帶的安裝可以將應用放到桌面生成快捷方式,但是有兩個問題: 一是不能自帶快捷鍵,需要手工另外增加; 二是開啟檔案位置找不到安裝目錄。 對於第二個問

高階控制元件ListView以及定義介面卡

一 ListView 列表控制元件 使用的時候高度和寬度最好是設定為match_parent 二 自定義介面卡 1.BaseAdapter:是所有介面卡類的父類,可以對列表項進行最大限度的定製 2.寫一個類繼承自BaseAdapter,實現四個方法: get

07.HTML標籤以及定義定界符配置---《Beetl視訊課程》

本期視訊實現了評論列表分頁; 內容簡介:使用了標籤函式include完成分頁抽取 一起學beetl目錄:https://my.oschina.net/u/1590490?tab=newest&catalogId=6214598 作者:GK HTML標籤 Beetl 也支援HTML t