iOS 中 UITableView 某個場景的使用

最近在想關于 UITableView 的一些事,對于界面搭建來說,它是再常用不過了,對于它可以說的事,實在是太多了,然而我這兩天想的是應用場景的一些情形,其中有一些疑問。

多種樣式,多種點擊的列表
  • 1、多種點擊的列表,假如還是傳統方式,那么判斷是否太多了一點
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    switch (indexPath.row) {
        case 0: {
            
        }
            break;
        default:
            break;
    }
}

  • 2、多種樣式的列表,用一個 UITableViewCell 肯定是不行的
    此時肯定是多個 Cell ,甚至有種感覺此時不如直接用 UIButton 是否都會更方便一些,更好擴展一些呢?

  • 3、另外例如淘寶首頁這種界面,此時又該怎么辦呢?

復雜的 Home 界面

當然據說他們是采取了他們自己的 ListView, 此處不做討論,只是假如我們自己要實現的情況下,又應該怎么辦呢?

我想我的實現首先肯定是整體的 UICollectionView + HeaderView, 而此處復雜的是 HeaderView, 高度和滑動的實現,所以此處還是可以考慮到 UITableView 的,當然是特殊的 UITableView。


一、小嘗試,解決多種點擊(樣式相同)

之前我們在做個人頁面的時候,就是如上圖微信中的個人頁面一樣,樣式相同有多種點擊 ,我們之前組長封裝了一個方便點擊,樣式可調的工具。

  • 數據處理, 可以通過自己建立模型,給予分類。
SettingArrowItem *oneItem = [SettingArrowItem itemWithIcon:@"test_icon" title:@"First" destVcClass:[FirstViewController class]];
SettingArrowItem *twoItem = [SettingArrowItem itemWithIcon:@"test_icon" title:@"Second" destVcClass:[SecondViewController class]];

SettingGroup *groupOne = [[SettingGroup alloc] init];
groupOne.items = [NSMutableArray arrayWithArray:@[oneItem,twoItem]];
[self.dataArray addObject:groupOne];
  • 點擊,相當于之前已經做好選擇了,當然這樣的應用場景比較固定,也不利于擴展。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    // 1.模型數據
    SettingGroup *group = self.dataArray[indexPath.section];
    SettingItem *item = group.items[indexPath.row];
    // 2、箭頭可以點擊
    if ([item isKindOfClass:[SettingArrowItem class]]) {
        SettingArrowItem *arrowItem = (SettingArrowItem *)item;
        // 如果沒有需要跳轉的控制器
        if (arrowItem.destVcClass == nil) return;
        UIViewController *vc = [[arrowItem.destVcClass alloc] init];
        vc.title = arrowItem.title;
        [self.navigationController pushViewController:vc animated:YES];
    }
}

這一種處理,相當于是簡單的封裝數據,讓點擊時更方便,當然一些小部分的Cell 樣式也是可以任意改變的,然而還是認為應用場景有限,只能針對于Account 頁面的點擊,如微信那個人界面。

二、嘗試,解決多種樣式,多種點擊(樣式不同,點擊不同)

這是我們組長為更好的用 UITableView 特意做的一個數據管理器,ZHTableViewGroup,雖說有些細節處理不是很認同,特別是 Demo 中某兩處小細節,同時 Demo 也沒有呈現chu,但整體來說思路是很棒的,使用也是很方便的。

  • 數據處理,此處的點擊事件,已經放出來啦,樣式也是隨時可以改變啦
ZHTableViewGroup *group = [[ZHTableViewGroup alloc]init];
ZHTableViewCell *cellOne = [[ZHTableViewCell alloc]initWithTableView:self.homeTableView range:NSMakeRange(0, 6) cellHeight:44 cellClass:[HomeCellStyleOne class] identifier:KHomeCellStyleOneIdentifier];
cellOne.configCellComplete = ^(UITableViewCell *cell, NSIndexPath *indexPath) {
    HomeCellStyleOne *cellOne = (HomeCellStyleOne *)cell;
    cellOne.textLabel.text = @"One Title";
    cellOne.detailTextLabel.text = @"One Detail";
};
cellOne.didSelectRowComplete = ^(UITableViewCell *cell, NSIndexPath *indexPath) {
    NSLog(@"cell->%@,indexPath->%@",cell,indexPath);
};
[group addTableViewCell:cellOne];

ZHTableViewCell *cellTwo = [[ZHTableViewCell alloc]initWithTableView:self.homeTableView range:NSMakeRange(6, 5) cellHeight:44 cellClass:[HomeCellStyleTwo class] identifier:KHomeCellStyleOneIdentifier];
cellTwo.configCellComplete = ^(UITableViewCell *cell, NSIndexPath *indexPath) {
    HomeCellStyleOne *cellTwo = (HomeCellStyleOne *)cell;
    cellTwo.textLabel.text = @"Two Title";
    cellTwo.detailTextLabel.text = @"Two Detail";
};
cellTwo.didSelectRowComplete = ^(UITableViewCell *cell, NSIndexPath *indexPath) {
    NSLog(@"cell->%@,indexPath->%@",cell,indexPath);
};

[group addTableViewCell:cellTwo];
[self.dataSource addTableV
  • 而代理,一如既往是照舊,只是需要固定一些寫法。
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return self.dataSource.sectionNumber;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    ZHTableViewGroup *group = [self.dataSource groupWithIndex:section];
    return group.rowNumber;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ZHTableViewGroup *group = [self.dataSource groupWithIndex:indexPath.section];
    UITableViewCell *cell = [group cellWithIndexPath:indexPath];
    return cell;
}

#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ZHTableViewGroup *group = [self.dataSource groupWithIndex:indexPath.section];
    [group didSelectRowAtIndexPath:indexPath];
}

  • 關鍵方法:
/*!
 *  @brief 初始化cell托管的對象
 *
 *  @param tableView  cell所注冊的tableview
 *  @param range      cell的范圍
 *  @param cellHeight cell的高度
 *  @param cellClass  注冊cell的class
 *  @param identifier 注冊cell的標識符
 *
 *  @return ZHTableViewCell
 */
- (instancetype)initWithTableView:(UITableView *)tableView range:(NSRange)range cellHeight:(CGFloat)cellHeight cellClass:(Class)cellClass identifier:(NSString *)identifier;

此處,有很多細節方面,我不是很贊同其處理,例如 range Cell 的范圍,當然此種方式已經能滿足我們大部分的場景的(不是統一數據的類型那種)。

另外,類命名也不認同, ZHTableViewCell 是屬于一個 Manager 的,不應該直接命名為 Cell 結尾,容易讓人誤解。

三、看 《RETableViewManager》

于是我先去看看 RETableViewManager ,希望可以解決一些疑惑。這個輪子就是為了解決多種樣式多種點擊的列表。

直接看一下其 最基本用法:

- (void)viewDidLoad {
    [super viewDidLoad];
    // 總的 Manager
    self.manager = [[RETableViewManager alloc] initWithTableView:self.tableView];
    // Section 
    RETableViewSection *section = [RETableViewSection sectionWithHeaderTitle:@"Test"];
    [self.manager addSection:section];
    // Cell Item (基本的 Item)
    RETableViewItem *customItem = [RETableViewItem itemWithTitle:@"String cell" accessoryType:UITableViewCellAccessoryDisclosureIndicator selectionHandler:^(RETableViewItem *item) {
        NSLog(@"Test: %@", item);
    }];
    // Section Add Item
    [section addItem:customItem];
}

大致可以了解到 Cell ,Section 通通都由一個 RETableViewManager 來整體管理,而且 Cell 處的點擊和樣式都是單獨控制的,低耦合高內聚,這樣可以任意添加 Cell(此處的 Cell 都是基于其自定義的Cell),此處我的想法是自己是否也可以這樣做呢?當然 Cell 是任意的,并不要遵循某個BaseCell。

四、理解改善

其實ZHTableViewGroup 已經可以說對其樣式和對其點擊已經抽離出來了,但可以對 ZHTableViewGroup 進行三點改善,當然也是可商榷的。

  • 1、類命名更規范,將 ZHTableViewCell ==> ZHTableViewManager 相對來說更正確。
  • 2、將 Rang 抽離出來,這樣更利于理解和更利于優化。
    如果不寫,就是直接按照順序,一步一步添加上去,默認順序
  • 3、group 分組,實際還是可以蓋上成當真的分組時,自動有空行空出來,實際上換句話說就是可以說此處的結構還可以優化。

晉級: 將高度自適應,暫時沒進行,但是可以嘗試,不過從另一個角度來說,通常如果類似我想應用的場景,一般高度都是固定的,所以也沒必要,否則這個場景頁面就不知道什么情況啦。

例如:下面是我將其 Rang 取消后一個 Cell 往一個 Cell 的結果

@implementation ZHTableViewCell {
    NSRange _tempRange;
    UITableView *_tableView;
}

static NSUInteger number = 0;

- (instancetype)initWithTableView:(UITableView *)tableView cellHeight:(CGFloat)cellHeight cellClass:(Class)cellClass identifier:(NSString *)identifier {
    if (self = [super init]) {
        NSParameterAssert(tableView);
        NSParameterAssert(identifier);
        _tableView = tableView;
        NSDictionary *cellClassDict = [tableView valueForKey:@"_cellClassDict"];
        __block BOOL isExitRegister = NO;
        [cellClassDict.allKeys enumerateObjectsUsingBlock:^(NSString *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([obj isEqualToString:identifier]) {
                isExitRegister = YES;
            }
        }];
        if (!isExitRegister) {
            [tableView registerClass:cellClass forCellReuseIdentifier:identifier];
        }
        _tempRange = NSMakeRange(number, 1);
        number++;
        // _range = range;
        _cellHeight = cellHeight;
        _identifier = identifier;
    }
    return self;
}

- (BOOL)cellIsExitRangeWithIndex:(NSUInteger)index {
   // return NSLocationInRange(index, _range);
    return NSLocationInRange(index, _tempRange);
}

- (UITableViewCell *)cellWithIndexPath:(NSIndexPath *)indexPath {
    return [_tableView dequeueReusableCellWithIdentifier:_identifier forIndexPath:indexPath];
}

@end

此處這樣改完后,又發現沒必要,一步一步加上去雖說好用,但是脫離出來其實也沒必要,只是老覺的這樣一連串參數初始化 感覺怪怪的。

如后期繼續擴展維護,寫法和規范像 RETableViewManager 學習是必要的。

PS : 目前ZHTableViewGroup 上傳的 DEMO 還有問題,仔細看就知道了,哈哈。

五、知識點

  • _cellClassDict 作為 UITableView 的私有變量,保存 cellClass 和 cellIden 用的。

  • NSLocationInRange

NS_INLINE BOOL NSLocationInRange(NSUInteger loc, NSRange range) {
    return (!(loc < range.location) && (loc - range.location) < range.length) ? YES : NO;
}

類似這樣的內斂,有時效果還是很巧妙的

  • 當然更多的是對 UITableView 的熟悉度更加深了。


    效果圖

類似一連串的 View 的布局,我們就還是可以采用 UITableView, 可以解決上述淘寶 home 首頁那樣的問題,讓每一排 View 當做一個 Cell, 實現起來還是很方便的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,582評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,540評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,801評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,223評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,442評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,976評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,800評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,996評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,233評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,702評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容

  • 概述在iOS開發中UITableView可以說是使用最廣泛的控件,我們平時使用的軟件中到處都可以看到它的影子,類似...
    liudhkk閱讀 9,081評論 3 38
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,153評論 4 61
  • 1.form表單有什么作用?有哪些常用的input 標簽,分別有什么作用? 表單的作用是搜集用戶的輸入,用戶提交表...
    CYC_dc68閱讀 403評論 0 0
  • 只是你不知道而已
    馭臨風閱讀 197評論 0 1
  • 1.運營課程給我帶來最初的印象和思考 我在知道需要完成這么一次學習實踐,開始的我還是比較逃避的,通過三節課的課程學...
    時光聽得見閱讀 243評論 0 0