• Stars
    star
    106
  • Rank 325,871 (Top 7 %)
  • Language
    Objective-C
  • License
    MIT License
  • Created over 8 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A simple view model for building organized and scalable TableViews.

License MIT  CocoaPods  Platform  Support  Build Status

有赞logo

项目logo

A simple view model for building organized and scalable TableViews.

中文版README

SigmaTableViewModel vs UITableViewDataSource + UITableViewDelegate

Apple provides the UITableViewDataSource & UITableViewDelegate to implement the tableview UI, but a big problem is that the UI logic exists in multiple places and there will be lots of duplicate code, especially those complex tableview UIs with different types of cells and dynamic logic.

e.g. Let's take a look at a store management UI like this:

2 kinds of users will use this UI, manager and employee. Manager can see all above rows, while employee can only see some of them, like

In the traditional way, we may implement the UI like this:

#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    switch (self.type) {
        case MemberTypeEmployee:
            return 3;
            break;
        case MemberTypeManager:
            return 4;
            break;
        default:
            return 3;
            break;
    }
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section == 0) {
        if (self.type == MemberTypeEmployee) {
            return 1;  // only store info
        } else {
            return 2;  // store info and goods entry
        }
    } else if (section == 1) {
        if (self.type == MemberTypeEmployee) {
            return 2;  // order list
        } else {
            return 3;  // advanced settings...
        }
    } else if (section == 2) {
        if (self.type == MemberTypeEmployee) {
            return 1;  // about
        } else {
            return 3;  // store income and withdraw
        }
    } else {
        return 1;  // about
    }
}
... 

There will be more if else code in the rest datasrouce & delegate methods, especially in the tableView:cellForRowAtIndexPath: method. Take a look at the code in BadTableViewController in the demo for more details.

We can see the problem here. There are so many hardcode things and duplicate code. What we need is to use a model to hold all the logic and only use the model in these delegate & datasource methods. That is what the SigmaTableViewModel does.

SigmaTableViewModel provides the YZSTableViewModel as the view model and a depth 2 array sectionModelArray in it. The 1st level of the array is the section, and the 2nd level is the row. So what we need is to construct this array and ask tableview to use it, like this:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.viewModel = [[YZSTableViewModel alloc] init];
    self.tableView.delegate = self.viewModel;
    self.tableView.dataSource = self.viewModel;
    [self initViewModel];
    [self.tableView reloadData];
}
- (void)initViewModel {
    [self.viewModel.sectionModelArray removeAllObjects];
    [self.viewModel.sectionModelArray addObject:[self storeInfoSection]];
    if (self.type == MemberTypeManager) {
        [self.viewModel.sectionModelArray addObject:[self advancedSettinsSection]];
    }
    [self.viewModel.sectionModelArray addObject:[self incomeInfoSection]];
    [self.viewModel.sectionModelArray addObject:[self otherSection]];
}
- (YZSTableViewSectionModel*)storeInfoSection {
    YZSTableViewSectionModel *sectionModel = [[YZSTableViewSectionModel alloc] init];
    ...
    // store info cell
    YZSTableViewCellModel *cellModel = [[YZSTableViewCellModel alloc] init];
    [sectionModel.cellModelArray addObject:cellModel];
    cellModel.height = 80;
    cellModel.renderBlock = ^UITableViewCell *(NSIndexPath *indexPath, UITableView *tableView) {
        ...
    };
    if (self.type == MemberTypeManager) {
        // product list cell
        YZSTableViewCellModel *cellModel = [[YZSTableViewCellModel alloc] init];
        [sectionModel.cellModelArray addObject:cellModel];
        cellModel.renderBlock = ^UITableViewCell *(NSIndexPath *indexPath, UITableView *tableView) {
            ...
        };
        cellModel.selectionBlock = ^(NSIndexPath *indexPath, UITableView *tableView) {
            [tableView deselectRowAtIndexPath:indexPath animated:YES];
            ...
        };
    }
    return sectionModel;
}
...

Take a look at the code in the GoodTableViewController in the demo for more details.

Exercise

If we want to move the Withdraw row to the 3rd row in that section, what do we need to do in the traditional way? And how about in SigmaTableViewModel way? What if we what to hide the Income row for employee?

Usage

2 steps to use the SigmaTableViewModel.

  1. Create an instance of the YZSTableViewModel and use it as the tableview's delegate and datasource.
  2. Construct the sectionModelArray for the view model instance.

Installation

CocoaPods

  1. Add pod 'SigmaTableViewModel' to your Podfile.
  2. Run pod install or pod update.

Manually

  1. Download all the files in the Lib subdirectory.
  2. Add the source files to your Xcode project.

More Discussions

  • SigmaTableViewModel only provides some frequently used functions of UITableViewDataSource & UITableViewDelegate. If you needs more functions, you can subclass YZSTableViewModel and implement those functions.
  • If the code in those cell's blocks can be reused, we can put them in some methods and only invoke these methods in those blocks.
  • The block is used frequently in the view model so we have to be careful about the retain cycle. Always use weak-strong dance for safe. In the demo, we use YZWeak & YZStrong macros to simplify the weak-strong dance code.

License

MIT

More Repositories

1

vant

A lightweight, customizable Vue UI library for mobile web apps.
TypeScript
23,055
star
2

vant-weapp

轻量、可靠的小程序 UI 组件库
JavaScript
17,673
star
3

zent

A collection of essential UI components written with React.
TypeScript
2,246
star
4

zan-proxy

An extensible proxy for PC/Mobile/APP developer
TypeScript
1,814
star
5

vant-demo

Collection of vant demos.
Vue
1,560
star
6

zanphp

PHP开发面向C10K+的高并发SOA服务 和RPC服务首选框架
PHP
1,437
star
7

nsq

A realtime distributed messaging platform (forked from https://github.com/nsqio/nsq)
Go
633
star
8

zanui-weapp

本仓库已不再维护,请移步 https://github.com/youzan/vant-weapp
JavaScript
535
star
9

bugCatcher

方便产品、开发、测试三方协同管理、测试、监控项目进度和质量,以持续交付。
Java
491
star
10

zan

高效稳定、安全易用、线上实时验证的全异步高性能网络库,通过PHP扩展方式使用。
C
459
star
11

php-co-koa

PHP异步编程: 手把手教你实现co与Koa
459
star
12

Bifrost

A delightful library for app business modular architecture.
Objective-C
398
star
13

YZSpamFilter

有赞垃圾内容过滤工具
Python
283
star
14

TitanRecyclerView

A handy RecyclerView can deal with all headers, footers, and loading shit.
Java
249
star
15

tiny-loader.js

A small loader that load CSS/JS in best way for page performance
JavaScript
204
star
16

raven-weapp

Sentry SDK for WeApp
JavaScript
159
star
17

show-me-the-code

TypeScript
151
star
18

gatling-dubbo

A gatling plugin for running load tests on Apache Dubbo(https://github.com/apache/incubator-dubbo) and other java ecosystem.
Scala
149
star
19

felint

A smart way to eslint and stylelint for front end
JavaScript
127
star
20

weapp-plugin-demo

有赞微商城所有小程序插件的演示demo
JavaScript
113
star
21

YouzanMobileSDK-Android

有赞云AppSDK是为移动端应用打造的电商交易系统,通过一个SDK便可以在APP内集成有赞提供的整个交易服务。
Kotlin
113
star
22

httpfetch

对http请求进行封装的,通过对接口函数进行代理,实现优雅的http调用
Java
100
star
23

zanphp-doc

Zan PHP Framework doc
Python
99
star
24

zan_high_performance_mysql

mysql performance optimize book
98
star
25

beeyz

beeyz
Java
86
star
26

sprite-loader

A image sprite loader for webpack.
JavaScript
83
star
27

fast-uglifyjs-plugin

hight performance uglify plugin for webpack
JavaScript
71
star
28

systemtap-toolkit

YouZan systemtap toolkit to online analyze on production
Perl
69
star
29

ngx_http_ipip_module

nginx http module for ipip.net
C
65
star
30

YouzanMobileSDK-iOS

有赞云AppSDK是为移动端应用打造的电商交易系统,通过一个SDK便可以在APP内集成有赞提供的整个交易服务。
Objective-C
62
star
31

zanhttpdemo

HTTP demo for Zan PHP Framework
PHP
57
star
32

go-nsq

Go
56
star
33

open-sdk-php

有赞云网关 SDK for PHP
PHP
54
star
34

php-nsq-client

php nsq client
PHP
38
star
35

nsqJavaSDK

nsq client for java
Java
37
star
36

vue-cli-template-vant

注意:本仓库适用于 vue-cli 2.0, vue-cli 3.0 请参考:https://youzan.github.io/vant/#/zh-CN/quickstart
JavaScript
35
star
37

youzan-sdk

Yet Another Node.js SDK for http://open.youzan.com
JavaScript
33
star
38

zent-kit

[DEPRACATED] React 组件库开发脚手架
JavaScript
28
star
39

vant-doc

本仓库已废弃,请使用 https://github.com/youzan/vant/tree/dev/packages/vant-cli
Vue
27
star
40

zan-installer

Youzan Zan Php Installer
PHP
26
star
41

zan-tool

Zan Node Web 框架配套开发工具
JavaScript
23
star
42

yz-cloud-boot

有赞云有容器应用PHP框架
PHP
21
star
43

open-sdk-node

有赞云网关 SDK for Node
JavaScript
20
star
44

vant-icons

本仓库已迁移至 https://github.com/youzan/vant/tree/dev/packages/vant-icons
CSS
18
star
45

zan-thrift

zan thrift代码生成工具
C++
17
star
46

create-utils

Build your own js library by running one command
JavaScript
15
star
47

ngx_http_html_sanitize_module

It's a nginx http module to sanitize HTML5 with whitelisted elements, whitelisted attributes and whitelisted CSS property
HTML
15
star
48

zanphp.io-server

Proudly build with Zan PHP Framework
CSS
13
star
49

open-sdk-Csharp

有赞云网关Api调用C# SDK
C#
12
star
50

spark-nsq-consumer

spark-nsq-consumer
Scala
10
star
51

zent-seed

[DEPRECATED] React 组件库项目模版,请配合 https://github.com/youzan/zent-kit 使用
JavaScript
8
star
52

felint-config

Shell
6
star
53

yz_aerospike

youzan aerospike client branch
C
6
star
54

zan-doc

PHP
5
star
55

zanphp.io

Zan PHP Framework official site
CSS
5
star
56

zan-utils

TypeScript
4
star
57

zantcpdemo

PHP
4
star
58

zanwebsocketdemo

PHP
4
star
59

extension-point-api

有赞云扩展点PHP桩代码
PHP
4
star
60

zanhttp-boilerplate

Youzan ZanPhp HTTP project Boilerplate
PHP
4
star
61

zent-beta

Zent beta 版文档网站
HTML
3
star
62

YouzanHarmonySDK

Batchfile
2
star
63

cloud-connector-doc

云连接器文档
Shell
2
star
64

eslint-plugin-youzan

Eslint plugin for youzan
JavaScript
2
star
65

yz-cloud-boot-demo-app

有赞云有容器App定制PHP测试Demo工程
JavaScript
2
star
66

youzan.github.io

HTML
1
star
67

vue-cli-template-yzae

A vue-cli template for youzan app-engine developer, forked from vue-cli-template-vant.
JavaScript
1
star
68

zantcp-boilerplate

Youzan ZanPHP TCP project Boilerplate
PHP
1
star
69

zan-snippets

Code snippets for various editors at Youzan
Shell
1
star
70

zan-user-guide

Python
1
star
71

zanwebsocket-boilerplate

PHP
1
star