類似索引Model套Model之 iOS模型閑聊二

看下界面, 這是類似于索引的頁面, 只不過木有右側(cè)索引條的布局. 如果想了解通訊錄索引的,請移步iOS - 高仿通訊錄之商品索引排序搜索.

盤點記錄.png

提供思路如下:

  1. 分析界面及接口
  2. 用 MVC 設計模式來實現(xiàn)(其實核心點都在下面5)
  3. 創(chuàng)建內(nèi)外層 Model 并綁定兩者 Model
  4. 兩者 Cell 布局的實現(xiàn) (便于后期界面的快速更改)
  5. 在外層控制器內(nèi)進行邏輯操作并請求數(shù)據(jù)的分區(qū)及每個分區(qū)行數(shù)的處理.
    5.1 創(chuàng)建一個保存數(shù)據(jù)的數(shù)組timeList, 這個數(shù)組是外層列表數(shù)組(分區(qū)時間數(shù)組)
    5.2 拿到數(shù)組后, 就可以考慮分區(qū)數(shù)目及當前分區(qū)下 cell 數(shù)目
    5.3 創(chuàng)建header的界面及數(shù)據(jù)
    5.4 找到相對應的分區(qū)去帶回內(nèi)層數(shù)組
  6. 跳轉(zhuǎn)控制器內(nèi)層數(shù)組的傳值簡單實現(xiàn).

Step1. 分析界面及接口

首先我們先分析這個界面:
很明顯這是一個 tableView 的多分區(qū)多cell的布局.
這樣就好辦許多,截取一個分區(qū)來做說明.


很明顯的能看出來, 這必須只能是 Model 套 Model 了. 分析下接口:


接口分析

Step2. 用 MVC 設計模式來實現(xiàn).

大致思路有了,那我們接著該整理 MVC 了.
簡單來說, 就是創(chuàng)建兩套 MVC: 外層盤點記錄的 MVC 與 內(nèi)層盤點詳情的 MVC(其中內(nèi)層的還包括外層盤點記錄下的每個當前分區(qū)下的記錄 cell 詳情).
看起來是兩套 MVC, 由于我們內(nèi)層的兩個數(shù)組里字典數(shù)據(jù)是一樣的模型, 我就共用了一套內(nèi)層 M, 其實是三部分的交錯使用.
看個點擊分區(qū)跳轉(zhuǎn)到盤點詳情的 MVC 界面:


盤點詳情.png

Step3. 創(chuàng)建內(nèi)外層 Model 并綁定兩者 Model

由于只提供思路,就只放核心部分代碼.
先創(chuàng)建內(nèi)層的 子Model(YYPRecordDetailsModel)就和一般正常的 Model 創(chuàng)建一樣就好,

// 時間
@property (nonatomic, copy) NSString *dotime;

// 商品名稱
@property (nonatomic, copy) NSString *commodityName;

// 商品金額
@property (nonatomic, assign) float commodityAmt;

// 實際盤點數(shù)量
@property (nonatomic, assign) NSInteger inventoryNum;

// 庫存數(shù)量
@property (nonatomic, assign) NSInteger stockNum;

接著創(chuàng)建外層的 一級Model(YYPInventoryRecordModel), 除了幾個基本單元素外, 兩個內(nèi)層數(shù)組是子 Model 不要忘了要放進去.

// 詳情全部數(shù)據(jù)
@property (nonatomic, strong) NSArray *inventoryList;

// 虧盈數(shù)據(jù)
@property (nonatomic, strong) NSArray *inventoryList2;

最后在外層 Model 的. m 里實現(xiàn)兩者的綁定.

+ (NSDictionary *)objectClassInArray {
    
    return @{@"inventoryList" : [YYPRecordDetailsModel class], @"inventoryList2" : [YYPRecordDetailsModel class]};
}

Step4. 兩者 Cell 布局的實現(xiàn)

頁面都是根據(jù)產(chǎn)品和 UI 確定, 我們單獨寫UITableViewCell, 好處就是便于后期界面的快速更改.

可以根據(jù)自己的界面來寫. 我這里就記錄下 Model 賦值. 一定切記,選擇相對應的 Model. 我這里展示分區(qū)下的 cell 就相對應的是子Modle.

// model賦值
- (void)setModel:(YYPRecordDetailsModel *)model {
    
    _model = model;
    
    // 商品名稱
    self.commodityName.text = [NSString stringWithFormat:@"%@", model.commodityName];
    
    // 單價
    self.commodityAmt.text = [NSString stringWithFormat:@"¥%.2f", model.commodityAmt];
    
    // 盈虧
    if (model.inventoryNum >= model.stockNum) {
        self.result.textColor = YYPGrayTitleColor;
        
        if (model.inventoryNum > model.stockNum) {
            self.result.text = [NSString stringWithFormat:@"+%ld", (model.inventoryNum - model.stockNum)];
        } else {
            self.result.text = @"0";
        }
    } else if (model.inventoryNum < model.stockNum) { // 虧
        self.result.textColor = YYPRedTitleColor;
        
        self.result.text = [NSString stringWithFormat:@"-%ld", (model.stockNum - model.inventoryNum)];
    }
}

Step5. 在外層控制器內(nèi)進行邏輯操作并請求數(shù)據(jù)的分區(qū)及每個分區(qū)行數(shù)的處理.

其實這里就是重點核心部分了!我要劃重點啦~

5.1 看盤點記錄界面, 就是一個TableView, 那么我們創(chuàng)建一個保存數(shù)據(jù)的數(shù)組timeList, 這個數(shù)組是外層列表數(shù)組(分區(qū)時間數(shù)組).

@property (nonatomic, strong) NSMutableArray *timeList;
- (NSMutableArray *)timeList {
    if (!_timeList) {
        _timeList = [NSMutableArray array];
        
    }
    return _timeList;
}

PS: 切記!!!千萬不要再創(chuàng)建內(nèi)層數(shù)組,容易把自己繞糊涂, 有了外層數(shù)組,需要內(nèi)層數(shù)組數(shù)據(jù)時是可以通過外層數(shù)組 timeList 去獲取的.譬如行數(shù)據(jù):model.inventoryList2[indexPath.row]

5.2 拿到數(shù)組后, 就可以考慮分區(qū)數(shù)目及當前分區(qū)下 cell 數(shù)目

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    self.tableView.mj_footer.hidden = self.timeList.count == 0;
    return self.timeList.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    YYPInventoryRecordModel *model = self.timeList[section];
    return model.inventoryList2.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    YYPInventoryRecordDetailCell *detailCell = [YYPInventoryRecordDetailCell cellWithTableView:tableView];
    if (self.timeList.count) { // 有時候傳值為nil
        YYPInventoryRecordModel *model = self.timeList[indexPath.section];
        YYPRecordDetailsModel *detailModel = model.inventoryList2[indexPath.row];
        detailCell.model = detailModel;
    }
    return detailCell;
}

#pragma mark - UITableViewDelegate

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
    
    return YYPInventoryRecordDetailCellHeight;
}

5.3 這個時候盤點記錄的 cell詳情出來了, 接著考慮header的界面及數(shù)據(jù).

viewForHeaderInSection里創(chuàng)建

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section ;

賦值取當前一級 Model 下字段: [[_timeList objectAtIndex:section] valueForKey:@"dotime"]];

 dotime.text = [NSString stringWithFormat:@"%@", [[_timeList objectAtIndex:section] valueForKey:@"dotime"]];

分區(qū)Header內(nèi)容也是由外層 Model 賦值的, 返回每個分區(qū)的內(nèi)容self.timeList[section]

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    
    return self.timeList[section];
}

5.4 由于我們還有下個跳轉(zhuǎn)頁面,同時還是取當前接口數(shù)據(jù), 這個時候我們就要找到相對應的分區(qū)去跳轉(zhuǎn)即可.

在cell 點擊跳轉(zhuǎn)相對來說方便的多,因為這個有系統(tǒng)方法didSelectRowAtIndexPath.只需要找到相對應分區(qū)self.timeList[indexPath.section]

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    YYPInventoryRecordModel *model = self.timeList[indexPath.section];
    YYPRecordDetailsController *vc = [[YYPRecordDetailsController alloc] init];
    vc.inventoryList = model.inventoryList;
    [self.navigationController pushViewController:vc animated:YES];
}

若是header 上也要實現(xiàn)按鈕跳轉(zhuǎn), 可以在viewForHeaderInSection方法里的按鈕上加個標記與header的分區(qū)section一致, 然后找到相對應分區(qū)self.timeList[sender.tag]就好.

 inIcon.tag = section;

實現(xiàn)跳轉(zhuǎn)方法

- (void)btnClick:(UIButton *)sender {

    // 用 tag 來標記section
    YYPInventoryRecordModel *model = self.timeList[sender.tag];
    YYPRecordDetailsController *vc = [[YYPRecordDetailsController alloc] init];
    vc.inventoryList = model.inventoryList;
    [self.navigationController pushViewController:vc animated:YES];
}

5.5 最后就是請求了.

拿到最外層的數(shù)組數(shù)據(jù)就好.

[weakSelf.timeList removeAllObjects];
NSArray *currentPageArray = [YYPInventoryRecordModel loadInventoryRecordInfoFromJson:json[@"data"]];
[weakSelf.timeList addObjectsFromArray:currentPageArray];

至于上拉加載更多數(shù)據(jù)/下拉刷新新數(shù)據(jù) 及 網(wǎng)絡不佳狀態(tài)重新加載獲取請求這些都是按自己項目需求添加的. 這里就不一一展示了.

Step6. 跳轉(zhuǎn)控制器內(nèi)層數(shù)組的傳值簡單實現(xiàn).

這其實就是一個簡單的正常的 MVC. 就是不需要請求接口,就是正向傳值帶回來一個數(shù)組.
.h 里露出一個屬性便于傳值.

// 詳情全部數(shù)據(jù)
@property (nonatomic, strong) NSArray *inventoryList;

在. m 里創(chuàng)建一個保存接收數(shù)據(jù)的可變數(shù)據(jù)

// 詳情全部數(shù)據(jù)
@property (nonatomic, strong) NSMutableArray *goodList;

需要加載inventoryList數(shù)據(jù)帶回到goodList.

#pragma mark - 懶加載

- (NSMutableArray *)goodList {
    if (!_goodList) {
        _goodList = [NSMutableArray array];
        
        [_goodList addObjectsFromArray:_inventoryList];
    }
    return _goodList;
}

簡單的Table view data source方法:

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return self.goodList.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    YYPRecordDetailsCell *cell = [YYPRecordDetailsCell cellWithTableView:tableView];
    if (self.goodList.count) { // 有時候傳值為nil
        YYPRecordDetailsModel *model = self.goodList[indexPath.row];
        cell.model = model;
    }
    return cell;
}

這個時候,完整測試下效果吧:


盤點.gif

如果需要看訂單詳情頁那種Model 套 Model 的請移步: Model套Model之iOS模型閑聊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子段誊,更是在濱河造成了極大的恐慌藐石,老刑警劉巖咱台,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異僚稿,居然都是意外死亡,警方通過查閱死者的電腦和手機技羔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卧抗,“玉大人藤滥,你說我怎么就攤上這事∩珩桑” “怎么了拙绊?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長浦马。 經(jīng)常有香客問我时呀,道長,這世上最難降的妖魔是什么晶默? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任谨娜,我火速辦了婚禮,結(jié)果婚禮上磺陡,老公的妹妹穿的比我還像新娘趴梢。我一直安慰自己漠畜,他們只是感情好,可當我...
    茶點故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布坞靶。 她就那樣靜靜地躺著憔狞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪彰阴。 梳的紋絲不亂的頭發(fā)上瘾敢,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天,我揣著相機與錄音尿这,去河邊找鬼簇抵。 笑死,一個胖子當著我的面吹牛射众,可吹牛的內(nèi)容都是我干的碟摆。 我是一名探鬼主播,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼叨橱,長吁一口氣:“原來是場噩夢啊……” “哼典蜕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起罗洗,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤愉舔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后栖博,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屑宠,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年仇让,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片躺翻。...
    茶點故事閱讀 40,926評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡丧叽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出公你,到底是詐尸還是另有隱情踊淳,我是刑警寧澤,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布陕靠,位于F島的核電站迂尝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏剪芥。R本人自食惡果不足惜垄开,卻給世界環(huán)境...
    茶點故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望税肪。 院中可真熱鬧溉躲,春花似錦榜田、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疑枯,卻和暖如春辩块,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荆永。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工废亭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屁魏。 一個月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓滔以,卻偏偏與公主長得像,于是被迫代替她去往敵國和親氓拼。 傳聞我的和親對象是個殘疾皇子你画,可洞房花燭夜當晚...
    茶點故事閱讀 45,930評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,341評論 25 707
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,169評論 30 470
  • 傳統(tǒng)模式下的開發(fā)MVCMVVM基于面向協(xié)議MVP的介紹MVP實戰(zhàn)開發(fā)說在前面:相信就算你是個iOS新手也應該聽說過...
    行走的菜譜閱讀 3,165評論 1 5
  • 元音又稱母音撬统。所有元音的發(fā)音都需要張嘴振動聲帶适滓。幾乎所有的英文字都含有元音,因此我們可以說元音是構(gòu)成英文字發(fā)音的基...
    埃普麗爾腦子瓦特閱讀 1,389評論 0 2
  • 現(xiàn)在已經(jīng)是6點半了恋追,可是我還在去沙坪壩的車上凭迹,而且還不知道路上會不會堵車。到了沙坪壩還要去去擠輕軌苦囱。但這一切都不是...
    xiao錢錢閱讀 236評論 0 0