自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

iOS實現(xiàn)多個可變cell復(fù)雜界面的制作

移動開發(fā) iOS
由于評論內(nèi)容cell我們使用了Auto Layout,這樣就可以利用iOS 8 TableView的新特性,自動計算cell的高度。拼接完數(shù)據(jù)后,只要調(diào)用[self.tableView reloadData];讓TableView重新加載即可。

在日常的開發(fā)中,有時會遇到內(nèi)容塊比較多,且又可變的界面: 

 

 

iOS 實現(xiàn)多個可變 cell 復(fù)雜界面的制作

 

這個界面中有些內(nèi)容塊是固定出現(xiàn)的,比如最上面的商品詳情圖片、商品名稱、價格等。而有些內(nèi)容塊則是不一定出現(xiàn)的,比如促銷(顯然不是每個商品都有促銷)、已選規(guī)格(有的商品沒有規(guī)格)、店鋪信息(有的商品屬于自營,就沒有店鋪)等。還有些內(nèi)容要根據(jù)情況進(jìn)行變化,比如評論,這里最多列出4條評論,如果沒有評論,則顯示“暫無評論”且不顯示“查看所有評論”按鈕。

對于這樣的界面,相信很多人***感覺會用TableView來做,因為中間要列出評論內(nèi)容,這個用TableView的cell來填充比較合適。但如何處理評論內(nèi)容之外的其他內(nèi)容呢?我之前的做法是,評論內(nèi)容之上的用HeaderView做,下面的用FooterView做,雖然最終實現(xiàn)了功能,但做起來十分麻煩。布局我是用Auto Layout來做的,由于Auto Layout本身的特點(diǎn),代碼中就涉及很多判斷處理。比如“已選規(guī)格”塊,最開始的是有一個和“促銷”內(nèi)容塊的頂部間距約束,但“促銷”內(nèi)容塊不一定會有,就得根據(jù)情況,調(diào)整“已選規(guī)格”塊本身的約束(例如讓其頂部間距約束指向“價格”內(nèi)容塊)。同樣,“促銷”內(nèi)容塊本身也需要類似的處理,如果沒有“促銷”時,要隱藏自己,而隱藏自己最簡單的辦法,就是將自己的高度約束設(shè)置為0(因為它還有底部到“已選規(guī)格”的間距約束,不能隨意將自身移除,否則“已選規(guī)格”相關(guān)的約束得再進(jìn)行調(diào)整)。

此外,還有一個麻煩的問題。界面剛進(jìn)來的時候,是需要請求網(wǎng)絡(luò)數(shù)據(jù),這時界面就要顯示成一個初始狀態(tài),而顯然初始狀態(tài)有些內(nèi)容塊是不應(yīng)該顯示的,比如促銷,只有完成了數(shù)據(jù)請求,才能知道是否有促銷,有的話才顯示促銷內(nèi)容;比如評論,初始時應(yīng)該顯示成“暫無評論”,數(shù)據(jù)請求完成后,才顯示相應(yīng)的內(nèi)容。這樣,我們需要處理初始進(jìn)入和數(shù)據(jù)請求完成兩種狀態(tài)下各個內(nèi)容塊的顯示,十分復(fù)雜繁瑣。

總結(jié)來說,用TableView的 HeaderView + 評論內(nèi)容cell + FooterView + Auto Layout 的方式會帶來如下問題:

  1. 約束本身需要依賴其他View的,而所依賴的View又是可變的內(nèi)容塊,會導(dǎo)致約束需要繁瑣的判斷修改增刪
  2. 需要處理初始進(jìn)入和數(shù)據(jù)請求完成兩種狀態(tài)的界面展示,使代碼更加復(fù)雜繁瑣
  3. 需要額外計算相應(yīng)內(nèi)容的高度,以更新HeaderView、FooterView的高度

可見,這種方式并不是理想的解決方案??赡苡腥藭f,那不要用Auto Layout,直接操作frame來布局就好,這樣或許能減少一些麻煩,但總體上并沒有減少復(fù)雜度。也有人說,直接用ScrollView來做,這樣的話,所有的內(nèi)容包括評論內(nèi)容的cell,都得自己手動拼接,可以想象這種做法也是比較麻煩的。所以,我們得另辟蹊徑,使用其他方法來達(dá)到目的。下面就為大家介紹一種比較簡便的做法,這種做法也是一個前同事分享給我的,我就借花獻(xiàn)佛,分享給大家。

我們還是用TableView來做這個界面,和之前不同的是,我們把每一個可變內(nèi)容塊做成一個獨(dú)立的cell,cell的粒度可以自行控制,比如可以用一個cell囊括商品圖片、標(biāo)題、副標(biāo)題、價格,也可以拆得更細(xì),圖片、標(biāo)題、副標(biāo)題、價格都各自對應(yīng)一個cell。這里我們選擇后者,因為圖片內(nèi)容塊,我們需要按屏幕寬度等比例拉伸;標(biāo)題、副標(biāo)題的文字內(nèi)容可能是一行,也可能是兩行,高度可變,用單獨(dú)的cell來控制會更簡單明了。

下面先定義好各種類型的cell:

  1. //基礎(chǔ)cell,這里為了演示簡便,定義這個cell,其他cell繼承自這個cell 
  2.  
  3. @interface MultipleVariantBasicTableViewCell : UITableViewCell 
  4.  
  5. @property (nonatomic, weak) UILabel *titleTextLabel; 
  6.  
  7. @end 
  8.  
  9.   
  10.  
  11. //滾動圖片 
  12.  
  13. @interface CycleImagesTableViewCell : MultipleVariantBasicTableViewCell 
  14.  
  15. @end 
  16.  
  17.   
  18.  
  19. //正標(biāo)題 
  20.  
  21. @interface MainTitleTableViewCell : MultipleVariantBasicTableViewCell 
  22.  
  23. @end 
  24.  
  25.   
  26.  
  27. //副標(biāo)題 
  28.  
  29. @interface SubTitleTableViewCell : MultipleVariantBasicTableViewCell 
  30.  
  31. @end 
  32.  
  33.   
  34.  
  35. //價格 
  36.  
  37. @interface PriceTableViewCell : MultipleVariantBasicTableViewCell 
  38.  
  39. @end 
  40.  
  41.   
  42.  
  43. // ...其他內(nèi)容塊的cell聲明 
  44.  
  45.   
  46.  
  47.   
  48.  
  49. // 各種內(nèi)容塊cell的實現(xiàn),這里為了演示簡便,cell中就只放了一個Label 
  50.  
  51. @implementation MultipleVariantBasicTableViewCell 
  52.  
  53.   
  54.  
  55. - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 
  56.  
  57.     self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
  58.  
  59.     if (self) { 
  60.  
  61.         UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; 
  62.  
  63.         label.numberOfLines = 0; 
  64.  
  65.         [self.contentView addSubview:label]; 
  66.  
  67.         self.titleTextLabel = label; 
  68.  
  69.     } 
  70.  
  71.     return self; 
  72.  
  73.  
  74.   
  75.  
  76. @end 
  77.  
  78.   
  79.  
  80. @implementation CycleImagesTableViewCell 
  81.  
  82. @end 
  83.  
  84.   
  85.  
  86. @implementation MainTitleTableViewCell 
  87.  
  88. @end 
  89.  
  90.   
  91.  
  92. // ...其他內(nèi)容塊的cell實現(xiàn) 
  93.  
  94.   
  95.  
  96. // 評論內(nèi)容cell使用Auto Layout,配合iOS 8 TableView的自動算高,實現(xiàn)內(nèi)容自適應(yīng) 
  97.  
  98. @implementation CommentContentTableViewCell 
  99.  
  100.   
  101.  
  102. - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 
  103.  
  104.     self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
  105.  
  106.     if (self) { 
  107.  
  108.         self.titleTextLabel.translatesAutoresizingMaskIntoConstraints = NO
  109.  
  110.         self.titleTextLabel.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 8; 
  111.  
  112.         NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:self.titleTextLabel attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeLeading multiplier:1.0f constant:4.0f]; 
  113.  
  114.         NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:self.titleTextLabel attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:-4.0f]; 
  115.  
  116.         NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:self.titleTextLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeTop multiplier:1.0f constant:4.0f]; 
  117.  
  118.         NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:self.titleTextLabel attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-4.0f]; 
  119.  
  120.         [self.contentView addConstraints:@[leftConstraint, rightConstraint, topConstraint, bottomConstraint]]; 
  121.  
  122.     } 
  123.  
  124.     return self; 
  125.  
  126.  
  127.   
  128.  
  129. @end 

 

接下來就是重點(diǎn),就是如何來控制顯示哪些cell及cell顯示的數(shù)量。這一步如果處理不好,也會使開發(fā)變得復(fù)雜。如下面的方式:

  1. // 加載完數(shù)據(jù) 
  2.  
  3. self.cellCount = 0; 
  4.  
  5. if (存在促銷) { 
  6.  
  7.     self.cellCount++; 
  8.  
  9.  
  10. if (存在規(guī)格) { 
  11.  
  12.     self.cellCount++; 
  13.  
  14.  
  15. ...... 

 如果以這種方式來記錄cell的數(shù)量,那么后續(xù)cell的展示、點(diǎn)擊判斷等都會很麻煩。這里我們采用的方式是,使用單獨(dú)的類(作為一種數(shù)據(jù)結(jié)構(gòu))來保存所要展示的cell信息。

  1. // SKRow.h 
  2.  
  3. @interface SKRow : NSObject 
  4.  
  5.   
  6.  
  7. @property (nonatomic, copy) NSString *cellIdentifier; 
  8.  
  9. @property (nonatomic, strong) id data; 
  10.  
  11. @property (nonatomic, assign) float rowHeight; 
  12.  
  13.   
  14.  
  15. - (instancetype)initWithCellIdentifier:(NSString *)cellIdentifier 
  16.  
  17.                                   data:(id)data 
  18.  
  19.                              rowHeight:(float)rowHeight; 
  20.  
  21.   
  22.  
  23. @end 
  24.  
  25.   
  26.  
  27. // SKRow.m 
  28.  
  29. #import "SKRow.h" 
  30.  
  31.   
  32.  
  33. @implementation SKRow 
  34.  
  35.   
  36.  
  37. - (instancetype)initWithCellIdentifier:(NSString *)cellIdentifier data:(id)data rowHeight:(float)rowHeight { 
  38.  
  39.     if (self = [super init]) { 
  40.  
  41.         self.cellIdentifier = cellIdentifier; 
  42.  
  43.         self.data = data; 
  44.  
  45.         self.rowHeight = rowHeight; 
  46.  
  47.     } 
  48.  
  49.     return self; 
  50.  
  51.  
  52.   
  53.  
  54. @end  

SKRow用來存儲每個cell所需的信息,包括重用標(biāo)識、數(shù)據(jù)項、高度。接下來,我們就開始拼接cell信息。

  1. @interface ViewController () 
  2.  
  3. @property (nonatomic, strong) NSMutableArray *> *tableSections; 
  4.  
  5. @end 
  6.  
  7.  
  8. self.tableSections = [NSMutableArray array]; 
  9.  
  10.   
  11.  
  12. /* 初始加載數(shù)據(jù) 
  13.  
  14. * 初始化時,只顯示滾動圖片、價格、評論頭、無評論 
  15.  
  16. */ 
  17.  
  18. // 滾動圖片(寬高保持比例) 
  19.  
  20. SKRow *cycleImagesRow = [[SKRow alloc] initWithCellIdentifier:@"CycleImagesCellIdentifier" data:@[@"滾動圖片地址"] rowHeight:120*[UIScreen mainScreen].bounds.size.width / 320.f]; 
  21.  
  22. // 價格 
  23.  
  24. SKRow *priceRow = [[SKRow alloc] initWithCellIdentifier:@"PriceCellIdentifier" data:@"0" rowHeight:44]; 
  25.  
  26. [self.tableSections addObject:@[cycleImagesRow, priceRow]]; 
  27.  
  28. // 評論頭 
  29.  
  30. SKRow *commentSummaryRow = [[SKRow alloc] initWithCellIdentifier:@"CommentSummaryCellIdentifier" data:@{@"title":@"商品評價", @"count":@"0"} rowHeight:44]; 
  31.  
  32. // 無評論 
  33.  
  34. SKRow *noCommentRow = [[SKRow alloc] initWithCellIdentifier:@"NoCommentCellIdentifier" data:@"暫無評論" rowHeight:44]; 
  35.  
  36. [self.tableSections addObject:@[commentSummaryRow, noCommentRow]]; 

 以上是初始狀態(tài)時要顯示的cell,我們在ViewController中聲明一個數(shù)組,用來存儲TableView各個section要顯示的cell信息。這里我們將cell分成不同的section,實際中,要不要分,分成幾個section都可以自行決定。初始狀態(tài)我們有兩個section,***個section用于顯示基本信息,第二個section用于顯示評論信息,這樣就完成了cell信息的拼接,接下來就是顯示:

  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
  2.  
  3.     // 這里可以通過判斷cellIdentifier來區(qū)分處理各種不同的cell,cell所需的數(shù)據(jù)從row.data上獲取 
  4.  
  5.   
  6.  
  7.     SKRow *row = self.tableSections[indexPath.section][indexPath.row]; 
  8.  
  9.     if ([row.cellIdentifier isEqualToString:@"CycleImagesCellIdentifier"]) { 
  10.  
  11.         CycleImagesTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:row.cellIdentifier forIndexPath:indexPath]; 
  12.  
  13.         NSArray *urlStringArray = row.data; 
  14.  
  15.         cell.titleTextLabel.text = [urlStringArray componentsJoinedByString:@"\n"]; 
  16.  
  17.         return cell; 
  18.  
  19.     } else if ([row.cellIdentifier isEqualToString:@"MainTitleCellIdentifier"]) { 
  20.  
  21.         MainTitleTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:row.cellIdentifier forIndexPath:indexPath]; 
  22.  
  23.         cell.titleTextLabel.text = row.data; 
  24.  
  25.         return cell; 
  26.  
  27.     } else if ([row.cellIdentifier isEqualToString:@"PriceCellIdentifier"]) { 
  28.  
  29.         PriceTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:row.cellIdentifier forIndexPath:indexPath]; 
  30.  
  31.         cell.titleTextLabel.text = [NSString stringWithFormat:@"¥%@", row.data]; 
  32.  
  33.         return cell; 
  34.  
  35.     } else if ([row.cellIdentifier isEqualToString:@"SalePromotionCellIdentifier"]) { 
  36.  
  37.         SalePromotionTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:row.cellIdentifier forIndexPath:indexPath]; 
  38.  
  39.         NSArray *salePromotionStringArray = row.data; 
  40.  
  41.         cell.titleTextLabel.text = [salePromotionStringArray componentsJoinedByString:@"\n"]; 
  42.  
  43.         return cell; 
  44.  
  45.     } else if ([row.cellIdentifier isEqualToString:@"SpecificationCellIdentifier"]) { 
  46.  
  47.         SpecificationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:row.cellIdentifier forIndexPath:indexPath]; 
  48.  
  49.         cell.titleTextLabel.text = [NSString stringWithFormat:@"已選:%@", row.data]; 
  50.  
  51.         return cell; 
  52.  
  53.     } else if ([row.cellIdentifier isEqualToString:@"CommentSummaryCellIdentifier"]) { 
  54.  
  55.         CommentSummaryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:row.cellIdentifier forIndexPath:indexPath]; 
  56.  
  57.         NSDictionary *commentSummary = row.data; 
  58.  
  59.         cell.titleTextLabel.text = [NSString stringWithFormat:@"%@(%@)", commentSummary[@"title"], commentSummary[@"count"]]; 
  60.  
  61.         return cell; 
  62.  
  63.     } else if ([row.cellIdentifier isEqualToString:@"CommentContentCellIdentifier"]) { 
  64.  
  65.         CommentContentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:row.cellIdentifier forIndexPath:indexPath]; 
  66.  
  67.         cell.titleTextLabel.text = row.data; 
  68.  
  69.         return cell; 
  70.  
  71.     } else if ([row.cellIdentifier isEqualToString:@"AllCommentCellIdentifier"]) { 
  72.  
  73.         AllCommentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:row.cellIdentifier forIndexPath:indexPath]; 
  74.  
  75.         cell.titleTextLabel.text = row.data; 
  76.  
  77.         return cell; 
  78.  
  79.     } else if ([row.cellIdentifier isEqualToString:@"NoCommentCellIdentifier"]) { 
  80.  
  81.         NoCommentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:row.cellIdentifier forIndexPath:indexPath]; 
  82.  
  83.         cell.titleTextLabel.text = row.data; 
  84.  
  85.         return cell; 
  86.  
  87.     } 
  88.  
  89.     return nil; 
  90.  

 上面的代碼進(jìn)行了刪減,沒有處理所有類型。雖然稍嫌冗長,但是邏輯非常簡單,就是獲取cell信息,根據(jù)重用標(biāo)識來區(qū)分不同類型的內(nèi)容塊,將數(shù)據(jù)處理后放到cell中展示。

例如,對于商品圖片,因為是滾動圖片,滾動圖片可以有多張,前面我們傳入的數(shù)據(jù)就是數(shù)組data:@[@"滾動圖片地址"]。后面獲取到數(shù)據(jù)后,cell.titleTextLabel.text = [urlStringArray componentsJoinedByString:@"\n"];,出于演示,商品圖片cell我們只放了一個Label,所以只是簡單的將地址信息分行顯示出來。在實際的開發(fā)中,可以放入一個圖片滾動顯示控件,并將圖片地址的數(shù)組數(shù)據(jù)傳給控件展示。

其他類型的cell處理也是大同小異,出于演示的原因,都只是簡單的數(shù)據(jù)處理展示。當(dāng)然,別忘了,設(shè)置一下TableView相關(guān)的dataSource和delegate:

  1. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
  2.  
  3.     SKRow *row = self.tableSections[indexPath.section][indexPath.row]; 
  4.  
  5.     return row.rowHeight; 
  6.  
  7.  
  8.   
  9.  
  10. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
  11.  
  12.     return self.tableSections.count
  13.  
  14.  
  15.   
  16.  
  17. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
  18.  
  19.     return self.tableSections[section].count
  20.  

 這樣我們就完成了初始狀態(tài)時界面的展示 

 

 

 

完成了cell的顯示處理,接下來我們來模擬一下網(wǎng)絡(luò)請求數(shù)據(jù)后,界面如何顯示所需的cell

  1. self.tableSections = [NSMutableArray array]; 
  2.  
  3.   
  4.  
  5. NSMutableArray *section1 = [NSMutableArray array]; 
  6.  
  7. // 滾動圖片(寬高保持比例) 
  8.  
  9. SKRow *cycleImagesRow = [[SKRow alloc] initWithCellIdentifier:@"CycleImagesCellIdentifier" data:@[@"滾動圖片地址1", @"滾動圖片地址2", @"滾動圖片地址3"] rowHeight:120*[UIScreen mainScreen].bounds.size.width / 320.f]; 
  10.  
  11. // 主標(biāo)題 
  12.  
  13. SKRow *mainTitleRow = [[SKRow alloc] initWithCellIdentifier:@"MainTitleCellIdentifier" data:@"商品名稱" rowHeight:44]; 
  14.  
  15. // 副標(biāo)題 
  16.  
  17. SKRow *subTitleRow = [[SKRow alloc] initWithCellIdentifier:@"SubTitleCellIdentifier" data:@"節(jié)日促銷,快來買啊" rowHeight:44]; 
  18.  
  19. // 價格 
  20.  
  21. SKRow *priceRow = [[SKRow alloc] initWithCellIdentifier:@"PriceCellIdentifier" data:@(arc4random()) rowHeight:44]; 
  22.  
  23. [section1 addObjectsFromArray:@[cycleImagesRow, mainTitleRow, subTitleRow, priceRow]]; 
  24.  
  25. // 促銷(隨機(jī)出現(xiàn)) 
  26.  
  27. if (arc4random() % 2 == 0) { 
  28.  
  29.     SKRow *salePromotionRow = [[SKRow alloc] initWithCellIdentifier:@"SalePromotionCellIdentifier" data:@[@"促銷信息1", @"促銷信息2", @"促銷信息3"] rowHeight:44]; 
  30.  
  31.     [section1 addObject:salePromotionRow]; 
  32.  
  33.  
  34. [self.tableSections addObject:section1]; 
  35.  
  36.   
  37.  
  38. NSMutableArray *section2 = [NSMutableArray array]; 
  39.  
  40. // 規(guī)格(隨機(jī)出現(xiàn)) 
  41.  
  42. if (arc4random() % 2 == 0) { 
  43.  
  44.     SKRow *specificationRow = [[SKRow alloc] initWithCellIdentifier:@"SpecificationCellIdentifier" data:@"銀色,13.3英寸" rowHeight:44]; 
  45.  
  46.     [section2 addObject:specificationRow]; 
  47.  
  48.  
  49. if (section2.count > 0) { 
  50.  
  51.     [self.tableSections addObject:section2]; 
  52.  
  53.  
  54.   
  55.  
  56. NSMutableArray *section3 = [NSMutableArray array]; 
  57.  
  58. NSArray *commentArray = [NSMutableArray array]; 
  59.  
  60. // 評論內(nèi)容數(shù)據(jù)(隨機(jī)出現(xiàn)) 
  61.  
  62. if (arc4random() % 2 == 0) { 
  63.  
  64.     commentArray = @[@"評論內(nèi)容1", @"評論內(nèi)容2", @"2016年6月,蘋果系統(tǒng)iOS 10正式亮相,蘋果為iOS 10帶來了十大項更新。2016年6月13日,蘋果開發(fā)者大會WWDC在舊金山召開,會議宣布iOS 10的測試版在2016年夏天推出,正式版將在秋季發(fā)布。2016年9月7日,蘋果發(fā)布iOS 10。iOS10正式版于9月13日(北京時間9月14日凌晨一點(diǎn))全面推送。", @"評論內(nèi)容4"]; 
  65.  
  66.  
  67. // 評論頭 
  68.  
  69. SKRow *commentSummaryRow = [[SKRow alloc] initWithCellIdentifier:@"CommentSummaryCellIdentifier" data:@{@"title":@"商品評價", @"count":@(commentArray.count)} rowHeight:44]; 
  70.  
  71. [section3 addObject:commentSummaryRow]; 
  72.  
  73. if (commentArray.count > 0) { 
  74.  
  75.     for (NSString *commentString in commentArray) { 
  76.  
  77.         // 評論內(nèi)容需要自適應(yīng)高度,高度值指定為UITableViewAutomaticDimension 
  78.  
  79.         SKRow *commentContentRow = [[SKRow alloc] initWithCellIdentifier:@"CommentContentCellIdentifier" data:commentString rowHeight:UITableViewAutomaticDimension]; 
  80.  
  81.         [section3 addObject:commentContentRow]; 
  82.  
  83.     } 
  84.  
  85.     // 查看所有評論 
  86.  
  87.     SKRow *allCommentRow = [[SKRow alloc] initWithCellIdentifier:@"AllCommentCellIdentifier" data:@"查看所有評論" rowHeight:44]; 
  88.  
  89.     [section3 addObject:allCommentRow]; 
  90.  
  91. else { 
  92.  
  93.     // 無評論 
  94.  
  95.     SKRow *noCommentRow = [[SKRow alloc] initWithCellIdentifier:@"NoCommentCellIdentifier" data:@"暫無評論" rowHeight:44]; 
  96.  
  97.     [section3 addObject:noCommentRow]; 
  98.  
  99.  
  100. [self.tableSections addObject:section3]; 
  101.  
  102.   
  103.  
  104. [self.tableView reloadData]; 

 上面的代碼同樣比較冗長,但邏輯也同樣十分簡單。按顯示順序拼湊cell數(shù)據(jù),有些不一定顯示的內(nèi)容塊,如促銷,則隨機(jī)判斷,如果顯示,將數(shù)據(jù)加入到section數(shù)組中[section1 addObject:salePromotionRow];。其他類型的cell也是類似的,不再贅述。要注意的是,評論內(nèi)容的文本可能有多行,我們將它的cell高設(shè)置為UITableViewAutomaticDimension:

[[SKRow alloc] initWithCellIdentifier:@"CommentContentCellIdentifier" data:commentString rowHeight:UITableViewAutomaticDimension];

由于評論內(nèi)容cell我們使用了Auto Layout,這樣就可以利用iOS 8 TableView的新特性,自動計算cell的高度。拼接完數(shù)據(jù)后,只要調(diào)用[self.tableView reloadData];讓TableView重新加載即可。

好了,這樣就大功告成 

 

 

 

最終效果

使用上述方式制作這種內(nèi)容塊可變的界面雖然寫起來較為啰嗦,但有如下優(yōu)點(diǎn):

  1. 邏輯清晰簡單,易于理解,視圖間不存在像先前HeaderView + Auto Layout + FooterView那種復(fù)雜的依賴,內(nèi)容塊的顯示與否處理非常簡便
  2. 易于調(diào)整。例如調(diào)換內(nèi)容塊的順序,只要移動下拼湊cell數(shù)據(jù)的代碼順序即可
  3. 易于擴(kuò)展增加新的內(nèi)容塊。要增加新的內(nèi)容塊,只需創(chuàng)建新的cell,在數(shù)據(jù)拼接時,增加拼接新cell類型的數(shù)據(jù)代碼,同樣在顯示的地方增加顯示新cell類型的代碼即可,幾乎不需要修改原有的邏輯

***,附上Demo工程代碼(https://github.com/kelystor/MultipleVariantCell)。注意,這個工程是用XCode 8創(chuàng)建的,低版本的XCode可能運(yùn)行會有問題(XCode 8的storyboard默認(rèn)好像不兼容老版本),示例是基于iOS 8,如果要兼容老版本,請自行修改(主要是涉及cell自動算高的部分)。

責(zé)任編輯:龐桂玉 來源: iOS大全
相關(guān)推薦

2011-04-08 11:13:10

2013-06-27 09:26:50

Android界面刷新

2012-03-28 11:17:48

JavaSSHJSP

2024-07-05 10:47:15

2009-08-05 14:17:27

ASP.NET錯誤頁面

2009-09-16 10:53:50

Flex界面

2020-06-18 10:25:16

Cockpit用戶界面運(yùn)維

2016-10-28 08:57:56

Git圖形界面

2012-03-09 13:52:28

Adob??e AIRiOS

2017-08-03 14:50:53

Windows 10Windows登錄界面

2018-11-01 17:06:06

cell自適應(yīng)高主

2009-09-08 11:07:16

Ubuntu 9.10安裝界面linux

2013-06-13 16:03:23

iOS7WWDC蘋果

2013-04-08 10:27:59

iOSXcode制作靜態(tài)庫

2009-11-12 11:18:28

VS Ribbon界面

2013-03-18 09:58:58

Windows 8

2014-11-27 10:58:22

SLAPaaS云服務(wù)

2009-12-01 18:33:15

Visual Stud

2011-07-22 16:15:11

IOS 靜態(tài)類

2011-06-21 09:33:49

Qt 啟動 界面
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號