不等高cell的搭建(一)

来源:http://www.cnblogs.com/xiaotian666/archive/2016/08/13/5749159.html
-Advertisement-
Play Games

一.界面搭建 1.確定開發模式 如果界面是固定的,可以用xib 界面的一些內容不固定,就用純代碼 cell用什麼方式去開發(我們採用純代碼和xib結合的方式) 2.劃分層次結構 2.1 怎麼劃分? 按照功能劃分 1.確定開發模式 如果界面是固定的,可以用xib 界面的一些內容不固定,就用純代碼 ce ...


 

一.界面搭建   1.確定開發模式      如果界面是固定的,可以用xib      界面的一些內容不固定,就用純代碼      cell用什麼方式去開發(我們採用純代碼和xib結合的方式)   2.劃分層次結構      2.1 怎麼劃分?           按照功能劃分           按照隱藏效果:在某些條件下,一些控制項要一起隱藏,就可以放在同一模塊中(前提是這些控制項集中在一起)        2.2 分析界面發現cell的middleView和commentView不確定要不要顯示           所以,cell採用純代碼方法搭建   3.自定義cell      3.1在創建cell的時候,就把所有可能顯示的模塊全部添加到cell上           把所有可能出現的模塊(控制項)全部添加到cell裡面,然後根據需求再決定某些模塊(控制項)是顯示還是隱藏        3.2根據伺服器數據,決定某些模塊是否隱藏        3.3在哪裡創建cell?           採用註冊的方法,底層會自動調用initWithStyle方法來創建cell   4.一個模塊一個模塊去搭建      4.1把cell分解為四個模塊,如上圖        4.2先把一個模塊所有的內容(搭建界面)和業務邏輯處理完,在去處理下一個模塊        4.3模塊的處理方式:先搭建界面,再處理界面業務邏輯        4.4優點:業務邏輯清晰,不容易混淆   二.topView模塊開發   1.xib搭建界面        1.1分析界面有哪些控制項來搭建        1.2自定義uiview並創建xib,描述好界面後,把界面添加到cell裡面        2.請求數據      2.1 查看介面文檔,使用afn發送網路請求        2.2網路請求成功時,把數據轉換成模型        2.3在模型中定義屬性(先自定義模型)           查看界面需要使用哪些數據,就找到定義數據的屬性定義到模型中        2.3自定義視圖模型,視圖模型包含模型(就是在視圖模型中定義一個模型的屬性)        2.4遍歷模型,全部轉換為視圖模型           創建視圖模型對象           用視圖模型的模型屬性來接收模型           把視圖模型保存到數組中   3.在視圖模型中計算cell子控制項的frame和高度         3.1什麼時候計算的            在模型轉視圖模型的時候計算的         3.2在哪裡計算的?            重寫視圖模型的模型屬性的set方法,在方法裡面計算cell的frame和高度,並定義屬性保存起來           因為,在模型轉視圖模型的時候,會把模型傳給視圖模型的模型屬性,底層會觸發視圖模型的模型屬性set方法,這個時候就去計算了        3.3 cell的高度計算           cell的高度就是Y軸方向最後一個控制項的最大Y值   4.展示數據        4.1怎麼展示?           在自定義cell裡面定義視圖模型屬性           創建cell之後,從數組中取出對應的視圖模型,給cell的視圖模型屬性賦值(觸發視圖模型的set方法)        4.2模型怎麼接收數據的?           在cell視圖模型屬性的set方法裡面,設置cell的frame和cell的高度(直接從視圖模型中去)           在把視圖模型的數據直接賦值給模型(觸發模型的set方法)           重寫模型的set方法,然後給界面的UI元素賦值,這樣就能在界面上看到數據了   5.註意點      5.1 cell會迴圈利用,設置某項屬性後,一定要記得還原      5.2 運行會報一些莫名其妙的約束衝突           是系統的自動拉伸約束有衝突,取消掉就可以了   三.middleView模塊搭建   middleView模塊的樣式也分很多種 我們可以利用xib搭建不同樣式的middleView,然後根據伺服器數據決定顯示哪種樣式的middleView 註意:一定要把其它樣式的middleView隱藏,還需要在其它地方還原,防止迴圈引用 根據需求我們可以把middleView分為四種樣式:   1.textView樣式      也就是沒有middleView,這種樣式只要不顯示middleView就可以了(把pictureView,videoView,voiceView隱藏)      也不需要計算frame的高度了   2.pictureView樣式                  

 

2.1 分析界面有哪些控制項組成, 界面怎麼搭建?           載入圖片的時候:有一個gif圖標,用ImageView來搭建,進度條可以放在一個view裡面                                      文字部分:如果是圖片用ImageView,如果是文字,用label或button都行, 需要與用戶交互就用button           顯示圖片時:圖片用ImageView搭建,下麵的查看大圖用button(有圖片和文字,還有背景圖片,還要與用戶交互,只能用button)           由於界面是固定的,可以採用xib來搭建   2.2 把pictureView添加到cel裡面   2.3 請求數據       2.4 在視圖模型中計算cell子控制項的frame和高度             2.4.1首先判斷數據是什麼類型的                返回的類型是NSInther,可讀性太差,可以定義枚舉來替代,可讀性就很好
1 typedef enum : NSUInteger {
2     XTThemeItemTypeAll = 1,
3     XTThemeItemTypeVideo = 41,
4     XTThemeItemTypeVoice = 31,
5     XTThemeItemTypePicture = 10,
6     XTThemeItemTypeText = 29
7 } XTThemeItemType;

 

          註意:定義枚舉的快捷鍵是:enum

 

            2.4.2 如果是text類型的就不需要計算了             2.4.3 如果圖片實際高度太高,我們就在模型裡面定義一個屬性來記錄是否是大圖             2.4.4 給大圖設置一個固定高度,不需要把大圖全部展示出來了
 1      // middleView:一樣計算方式
 2     // 不是段子的時候,才需要計算中間View的Frame
 3     if (item.type != XMGThemeItemTypeText) {
 4         CGFloat middleW = textW;
 5         CGFloat middleH = middleW / item.width * item.height;
 6         if (middleH > XTScreenH) {  // 大圖
 7             middleH = 300;
 8             item.is_bigPicture = YES;
 9         }
10         CGFloat middleX = margin;
11         CGFloat middleY = _cellH;
12         _middleViewFrame = CGRectMake(middleX, middleY, middleW, middleH);
13         _cellH = CGRectGetMaxY(_middleViewFrame) + margin;
14     }

 

  2.5 運行發現,如果是大圖,圖片就被壓縮了,很難看,怎麼解決?            ImageView預設是圖片填充的,就是把圖片拉伸或壓縮成整個ImageView的大小            設置ImageView的內容模式,不讓它壓縮 UIViewContentModeTop       2.6 設置內容模式,發現雖然圖片不被壓縮,但是圖片不能填充ImageView(兩邊是空的) 怎麼解決?           UIViewContentModeTop預設是圖片上面顯示到ImageView的頂部,但是不會進行拉伸或壓縮           我們需要先對圖片進行拉伸或壓縮處理,然後再設置 UIViewContentModeTop 就可以了       2.7 怎麼對圖片進行拉伸或壓縮處理?           可以用繪圖,生成一張新的拉伸或壓縮好的圖片       2.8 怎麼繪圖?           2.8.1 開啟圖形上下文           2.8.2 繪製圖片           2.8.3 獲取新的圖片           2.8.4 關閉圖形上下文       2.9 對圖片處理進行性能優化      2.9.1 每次設置圖片,都要進行繪圖,有可能重覆繪圖,性能不好,怎麼優化?           把處理好的圖片緩存到磁碟(沙盒)裡面,下次再設置這張圖片時,直接從磁碟取        2.9.2 怎麼對圖片緩存處理?           自己寫方法太麻煩, SDImageCache.h內部有方法緩存圖片,直接調用它的方法來進行緩存          
1   [[SDImageCache sharedImageCache] storeImage:image forKey:item.image0];
2           註意:要到入頭文件: #import <SDImageCache.h>

 

       2.9.3 怎麼從磁碟中去圖片?           同樣也是調用SDImageCache.h方法來取
        UIImage *image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.image0];

          註意:key值就是圖片的url

  2.10 剛開始載入圖片時,進度條怎麼設置?        2.10.1 需要設置一個功能模塊的時候,我們要先去找有沒有做該功能模塊的框架,有就直接拿來用        2.10.2 沒有的話,就找一個功能差不多的模塊來修改一下        2.10.3 怎麼去查找一個框架?           

 

 
 1            - (void)awakeFromNib
 2 {
 3     _progressView.progressLabel.textColor = [UIColor whiteColor];
 4     _progressView.progressTintColor = [UIColor whiteColor];
 5     _progressView.roundedCorners = 10;
 6     
 7     _progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",0.0 * 100];
 8     _progressView.progress = 0;
 9 }
10  
11 - (void)setItem:(XMGThemeItem *)item
12 {
13     _item = item;
14    
15     // 設置圖片
16     UIImage *image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.image0];
17     if (image) {   如果有圖片直接設置,並把進度設為100%
18         _imageView.image = image;
19         _progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",1.0 * 100];
20         _progressView.progress = 1;
21     } else {    如果沒有圖片,就先把進度設置為0 ,再去下載圖片
22         _progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",0.0 * 100];
23         _progressView.progress = 0;
24         // 下載網路圖片
25         [_imageView sd_setImageWithURL:[NSURL URLWithString:item.image0]  placeholderImage:nil options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) {
26             進度就為已下載的文件大小 / 總文件大小
27             CGFloat progress = 1.0 * receivedSize / expectedSize;
28             運行發現,進度有時候為-0,列印發現總文件大小該開始為-0       當為-0 的時候就返回
29           註意:該block會頻換調用,所以  returen一次沒關係
30             if (expectedSize < 0) return ;
31             _progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",progress * 100];
32             _progressView.progress = progress;
33            
34         } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
35            
36             if (!item.is_bigPicture) return ;
37            
38             // 生成一個新拉伸好圖片
39             CGFloat w = XMGScreenW - 20;
40             CGFloat h = w / item.width * item.height;
41            
42             // 開啟圖形上下文
43             UIGraphicsBeginImageContextWithOptions(CGSizeMake(w, h), NO, 0);
44             // 繪圖
45             [image drawInRect:CGRectMake(0, 0, w, h)];
46             // 獲取上下文圖片
47             image = UIGraphicsGetImageFromCurrentImageContext();
48             // 保存圖片到沙盒
49             [[SDImageCache sharedImageCache] storeImage:image forKey:item.image0];
50             // 關閉上下文
51             UIGraphicsEndImageContext();
52            
53             _imageView.image = image;  
54         }];
55     }
56     根據伺服器數據,決定gif圖片是否顯示
57     _gifView.hidden = !item.is_gif;
58      根據自己判斷保存的屬性,來決定顯示大圖按鈕是否顯示
59     _seeBigButton.hidden = !item.is_bigPicture;
60  
61     if (item.is_bigPicture) {
62         _imageView.contentMode = UIViewContentModeTop;
63         _imageView.clipsToBounds = YES;
64     } else {
65         _imageView.contentMode = UIViewContentModeScaleToFill;
66         _imageView.clipsToBounds = NO;
67     }
68 }

 

3.videoView樣式  和  voiceView樣式  

 

            3.1 由於這兩個模塊基本相同,處理方法也差不多      註意:把搭建好的xib的view拷貝到另一個xib裡面的時候,會把對應的連線也拷過去,一定要先刪除這些連線,再繼續使用      

 

  3.2 根據類型,只需要設置中間按鈕的圖片就可以了       3.3 xib搭建界面,並把界面添加到cell裡面      3.4 請求數據   3.5 在視圖模型中計算cell子控制項的frame和高度   3.6 展示數據        3.6.1 在videoView或voiceView的模型里設置數據的時候,要對數據進行處理        3.6.2 為什麼要處理?           伺服器返回的時間數據是以秒為單位的,需求以  00:00  來顯示        3.6.3 怎麼處理?  
1     NSInteger minute = item.voicetime / 60;
2     NSInteger second = item.voicetime % 60;
3     self.timeLabel.text = [NSString stringWithFormat:@"%02ld:%02ld",minute,second];

 

  4 在cell模型屬性的set方法裡面統一設置middleView各個模塊的frame的是否隱藏  
 1     // middleView
 2     if (vm.item.type == XMGThemeItemTypePicture) { // 圖片
 3         _pictureView.hidden = NO;
 4         _videoView.hidden = YES;
 5         _voiceView.hidden = YES;
 6        
 7         _pictureView.item = vm.item;
 8         _pictureView.frame = vm.middleViewFrame;
 9      
10     } else if (vm.item.type == XMGThemeItemTypeVideo) { // 視頻
11         _pictureView.hidden = YES;
12         _videoView.hidden = NO;
13         _voiceView.hidden = YES;
14        
15         _videoView.item = vm.item;
16         _videoView.frame = vm.middleViewFrame;
17     } else if (vm.item.type == XMGThemeItemTypeVoice) { // 音頻
18         _pictureView.hidden = YES;
19         _videoView.hidden = YES;
20         _voiceView.hidden = NO;
21        
22         _voiceView.item = vm.item;
23         _voiceView.frame = vm.middleViewFrame;
24        
25     } else {
26         _voiceView.hidden = YES;
27         _pictureView.hidden = YES;
28         _videoView.hidden = YES;
29     }

 

   
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • BOM
    一、改變 HTML 1.改變 HTML 輸出流 在 JavaScript 中,document.write() 可用於直接向 HTML 輸出流寫內容。 2.改變 HTML 內容 修改 HTML 內容的最簡單的方法時使用 innerHTML 屬性。 如需改變 HTML 元素的內容,請使用這個語法: 3 ...
  • HTML教程 一、HTML基礎(人) 1、基礎概念: 1.1、自動閉合標簽和閉合標簽(如出錯html編寫時不會報錯) 自閉合:<mete /> 閉合:<table>文字</table> 1.2、註釋:<!-- 文字 --> 1.3、標簽屬性(name): <table name="name"><ta ...
  • 當在Codeforces上做題的時,有時會無意撇到右側的Problem tags邊欄,但是原本並不希望能夠看到它。 能否把它屏蔽了呢?答案是顯然的,我們只需要加一段很短的CSS即可。 這樣,當這段CSS生效時,標簽將會變成如下所示的樣子。 這樣目的就達到了。 那麼,如何將CSS應用到瀏覽器中使其生效 ...
  • 1. 拿到項目之後 構思整個系統流程 展示所有的目錄信息 創建一個目錄 mkdir 打開目錄 顯示目錄下的所有文件 在目錄中 可以新建文件 在目錄中 可以對文件進行修改 2. 構思數據結構 需要存儲目錄的數據 需要存儲文件內容的數據 為了知道一個文件是屬於哪一個目錄 需要建立兩者的關聯 3. 構思實 ...
  • window.location 對象所包含的屬性 ...
  • 實現功能: 1、APP主界面底部模塊欄 2、ViewPager一屏多個界面顯示 3、........ 首先需要瞭解一下這個屬性的意思 ,即 是否允許子View超出父View的返回,有兩個值true 、false ,預設true 使用的時候給子View和根節點View控制項都設置android:clip ...
  • 先上圖 點擊+號就去選擇圖片 實際上這個添加本身就是一個ListView或者 RecyclerView 只是佈局有些特殊 item 在Adpater中判斷一個數據是不是為0和是不是最後一個添加的圖片就可以了。 這裡用到了一個正方形的,容器 這裡沒有寫圖片選擇器有興趣可以看這裡 圖片選擇器: http ...
  • 打開相機 打開相冊 onActivityResult OtherUtils ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...