Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6c11f49

Browse files
增加友好空白页视图,详见Example17
1. 增加数据源为空的占位视图 2. 提供`Example17`用来验证占位视图的有效性
1 parent 5aed0b2 commit 6c11f49

File tree

46 files changed

+741
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+741
-5
lines changed

‎MHDevelopExample/MHDevelopExample.xcodeproj/project.pbxproj

Lines changed: 162 additions & 0 deletions
Large diffs are not rendered by default.
Binary file not shown.

‎MHDevelopExample/MHDevelopExample/Architecture/BaseClass/ViewController/CMHTableViewController.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
/// 是否在上拉加载后的数据,dataSource.count < pageSize 提示没有更多的数据.default is YES 否则 隐藏mi_footer 。 前提是` shouldMultiSections = NO `才有效。
3333
@property (nonatomic, readwrite, assign) BOOL shouldEndRefreshingWithNoMoreData;
3434

35-
3635
/// 是否数据是多段 (It's effect tableView's dataSource 'numberOfSectionsInTableView:') defalut is NO,但是不能跟组头组尾相关联
3736
@property (nonatomic, readwrite, assign) BOOL shouldMultiSections;
3837

@@ -62,4 +61,8 @@
6261
///param reload 是否需要重载TabeleView
6362
- (void)tableViewDidFinishTriggerHeader:(BOOL)isHeader reload:(BOOL)reload;
6463

64+
65+
/// --------------- 2018年06月19日 新增API --------------
66+
67+
6568
@end

‎MHDevelopExample/MHDevelopExample/Architecture/BaseClass/ViewController/CMHTableViewController.m

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ - (void)tableViewDidTriggerFooterRefresh{
133133

134134
/// 结束刷新
135135
- (void)tableViewDidFinishTriggerHeader:(BOOL)isHeader reload:(BOOL)reload{
136+
136137
__weak typeof(self) weakSelf = self;
137138
dispatch_async(dispatch_get_main_queue(), ^{
138139
__strong typeof(weakSelf) strongSelf = weakSelf;
@@ -143,12 +144,14 @@ - (void)tableViewDidFinishTriggerHeader:(BOOL)isHeader reload:(BOOL)reload{
143144
if (isHeader) {
144145
/// 重置没有更多的状态
145146
if (self.shouldEndRefreshingWithNoMoreData){
147+
146148
[self.tableView.mj_footer setHidden:NO];
147149
[self.tableView.mj_footer resetNoMoreData];
150+
148151
}else{
152+
149153
[self.tableView.mj_footer setHidden:NO];
150154
}
151-
152155
[strongSelf.tableView.mj_header endRefreshing];
153156
}
154157
else{
@@ -163,9 +166,12 @@ - (void)tableViewDidFinishTriggerHeader:(BOOL)isHeader reload:(BOOL)reload{
163166

164167
#pragma mark - 辅助方法
165168
- (void)_requestDataCompleted{
166-
NSUInteger count = self.dataSource.count;
169+
167170
/// CoderMikeHe Fixed: 这里必须要等到,底部控件结束刷新后,再来设置无更多数据,否则被叠加无效
168-
if (self.shouldMultiSections) return; // 多组的不处理
171+
/// 多组的不处理
172+
if (self.shouldMultiSections) return;
173+
174+
NSUInteger count = self.dataSource.count;
169175

170176
if (count == 0 || count % self.perPage) {
171177

@@ -174,10 +180,10 @@ - (void)_requestDataCompleted{
174180
}else{
175181
self.tableView.mj_footer.hidden = YES;
176182
}
183+
177184
}
178185
}
179186

180-
181187
#pragma mark - Override
182188
- (UIEdgeInsets)contentInset{
183189
return UIEdgeInsetsMake(MH_APPLICATION_TOP_BAR_HEIGHT, 0, 0, 0);
Binary file not shown.

‎MHDevelopExample/MHDevelopExample/Architecture/Contacts/Contacts/CMHContactsViewController.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#import "CMHExample14ViewController.h"
1717
#import "CMHExample15ViewController.h"
1818
#import "CMHExample16ViewController.h"
19+
#import "CMHExample17ViewController.h"
1920
@interface CMHContactsViewController ()
2021

2122
@end
@@ -74,6 +75,9 @@ - (void)configure{
7475
example16.destClass = [CMHExample16ViewController class];
7576
[self.dataSource addObject:example16];
7677

78+
CMHExample *example17 = [[CMHExample alloc] initWithTitle:@"17:测试数据源为空显示占位视图" subtitle:@"详情请看`EmptyView`文件夹的内容"];
79+
example17.destClass = [CMHExample17ViewController class];
80+
[self.dataSource addObject:example17];
7781

7882
/// 刷洗数据
7983
// [self.tableView reloadData]; /// 等效下面的方法
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// CMHExample17ViewController.h
3+
// MHDevelopExample
4+
//
5+
// Created by lx on 2018年6月19日.
6+
// Copyright © 2018年 CoderMikeHe. All rights reserved.
7+
//
8+
9+
#import "CMHTableViewController.h"
10+
11+
@interface CMHExample17ViewController : CMHTableViewController
12+
13+
@end
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
//
2+
// CMHExample17ViewController.m
3+
// MHDevelopExample
4+
//
5+
// Created by lx on 2018年6月19日.
6+
// Copyright © 2018年 CoderMikeHe. All rights reserved.
7+
//
8+
9+
#import "CMHExample17ViewController.h"
10+
#import "CMHExampleTableTest.h"
11+
#import "CMHExampleTableTestCell.h"
12+
@interface CMHExample17ViewController ()
13+
14+
@end
15+
16+
@implementation CMHExample17ViewController
17+
/// 重写init方法,配置你想要的属性
18+
- (instancetype)init
19+
{
20+
self = [super init];
21+
if (self) {
22+
/// 支持上拉加载,下拉刷新
23+
self.shouldPullDownToRefresh = YES;
24+
self.shouldPullUpToLoadMore = YES;
25+
26+
/// 是否在用户上拉加载后的数据 , 如果请求回来的数据`小于` pageSize, 则提示没有更多的数据.default is YES 。 如果为`NO` 则隐藏mi_footer 。 前提是` shouldMultiSections = NO `才有效。
27+
self.shouldEndRefreshingWithNoMoreData = NO; // NO
28+
}
29+
return self;
30+
}
31+
- (void)viewDidLoad {
32+
[super viewDidLoad];
33+
/// 设置
34+
[self _setup];
35+
36+
/// 设置导航栏
37+
[self _setupNavigationItem];
38+
39+
/// 设置子控件
40+
[self _setupSubViews];
41+
42+
/// 布局子空间
43+
[self _makeSubViewsConstraints];
44+
}
45+
#pragma mark - 事件处理Or辅助方法
46+
- (void)_shuffle:(UIBarButtonItem *)sender{
47+
[MBProgressHUD mh_showProgressHUD:@"Loading..." addedToView:self.view];
48+
[self tableViewDidTriggerHeaderRefresh];
49+
}
50+
#pragma mark - Override
51+
- (void)tableViewDidTriggerHeaderRefresh{
52+
/// 下拉刷新事件 子类重写
53+
self.page = 1;
54+
/// 模拟网络
55+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
56+
/// hid HUD
57+
[MBProgressHUD mh_hideHUDForView:self.view];
58+
/// 假设就是没有数据
59+
60+
/// 现实场景中,我们利用AFNetworking访问服务器的数据,有成功的回调,和失败的回调,如下所示。
61+
/**
62+
///
63+
[CMHHttpRequestTool POST:UFMapListUrl params:params completion:^(NSURLSessionDataTask *task, id responseObject) {
64+
/// 请求成功的回调
65+
/// 若code == 200,则代表数据请求成功,否则则代表数据请求失败
66+
if ([responseObject[@"code"] integerValue]== 200) {
67+
/// 这里就代表请求成功,但是返回来的数据可能为空
68+
}else{
69+
/// 这里一般是服务器的问题,比如 服务器报500的错误,或者404的错误,以及503等等
70+
}
71+
} failed:^(NSURLSessionDataTask *task, NSError *error) {
72+
/// 请求失败的回调,
73+
/// 客户端一般只需要关心出错的原因是:
74+
/// - 网络问题
75+
/// - 服务器问题
76+
}];
77+
*/
78+
/// 以下模拟上面的网络请求回调 。 requestState == 0 则代表请求失败,反之,则代表请求成功
79+
NSInteger requestState = [NSObject mh_randomNumber:0 to:4];
80+
CMHEmptyDataViewType emptyType = [NSObject mh_randomNumber:0 to:9];
81+
if (requestState > 0) {
82+
83+
/// 服务器请求成功的返回的状态码 requestCode == 200 则代表有数据 , 反之则代表服务器出错
84+
NSInteger requestCode = [NSObject mh_randomNumber:199 to:205];
85+
86+
BOOL hasError = (requestCode < 200);
87+
88+
/// 请求成功的回调
89+
if (requestCode >= 200) { /// 这里假设>=200代表成功,增加一下模拟成功的几率
90+
/// 这里就代表请求成功,但是返回来的数据可能为空
91+
}else{
92+
/// 这里一般是服务器的问题,比如 服务器报500的错误,或者404的错误,以及503等等
93+
}
94+
[self.tableView cmh_configEmptyViewWithType:emptyType emptyInfo:nil errorInfo:nil offsetTop:250 hasData:self.dataSource.count>0 hasError:hasError reloadBlock:NULL];
95+
}else{
96+
/// 请求失败的回调,
97+
/// 客户端一般只需要关心出错的原因是:
98+
/// - 网络问题
99+
/// - 服务器问题
100+
/// 只需要设置 errorInfo 和 hasError == YES , hasData
101+
@weakify(self);
102+
[self.tableView cmh_configEmptyViewWithType:emptyType emptyInfo:nil errorInfo:nil offsetTop:250 hasData:self.dataSource.count>0 hasError:YES reloadBlock:^{
103+
@strongify(self);
104+
[MBProgressHUD mh_showProgressHUD:@"Loading..." addedToView:self.view];
105+
[self tableViewDidTriggerHeaderRefresh];
106+
}];
107+
}
108+
/// 告诉系统你是否结束刷新 , 这个方法我们手动调用,无需重写
109+
[self tableViewDidFinishTriggerHeader:YES reload:YES];
110+
111+
});
112+
}
113+
114+
- (void)tableViewDidTriggerFooterRefresh{
115+
/// 下拉加载事件 子类重写
116+
self.page = self.page + 1;
117+
118+
/// 模拟网络
119+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
120+
121+
/// hid HUD
122+
[MBProgressHUD mh_hideHUDForView:self.view];
123+
124+
125+
/// 假设第3页的时候请求回来的数据 < self.perPage 模拟网络加载数据不够的情况
126+
NSInteger count = (self.page >= 3)?18:self.perPage;
127+
/// 模拟数据
128+
for (NSInteger i = 0; i < count; i++) {
129+
NSString *title = [NSString stringWithFormat:@"这是第%ld条优秀数据",(long)(i + (self.page - 1) * self.perPage)];
130+
CMHExampleTableTest * et = [[CMHExampleTableTest alloc] init];
131+
et.idNum = i + (self.page - 1) * self.perPage;
132+
et.title = title;
133+
[self.dataSource addObject:et];
134+
}
135+
/// 告诉系统你是否结束刷新 , 这个方法我们手动调用,无需重写
136+
[self tableViewDidFinishTriggerHeader:NO reload:YES];
137+
138+
});
139+
}
140+
141+
142+
- (void)configure{
143+
[super configure];
144+
}
145+
146+
/// 生成一个可复用的cell
147+
- (UITableViewCell *)tableView:(UITableView *)tableView dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath{
148+
return [CMHExampleTableTestCell cellWithTableView:tableView];
149+
}
150+
151+
/// 为Cell配置数据
152+
- (void)configureCell:(CMHExampleTableTestCell *)cell atIndexPath:(NSIndexPath *)indexPath withObject:(id)object{
153+
[cell setIndexPath:indexPath rowsInSection:self.dataSource.count];
154+
[cell configureModel:object];
155+
}
156+
157+
158+
#pragma mark - UITableViewDelegate
159+
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
160+
[tableView deselectRowAtIndexPath:indexPath animated:YES];
161+
162+
CMHExampleTableTest *et = self.dataSource[indexPath.row];
163+
CMHViewController *temp = [[CMHViewController alloc] initWithParams:nil];
164+
temp.title = [NSString stringWithFormat:@"%ld条数据",et.idNum];
165+
[self.navigationController pushViewController:temp animated:YES];
166+
}
167+
168+
169+
#pragma mark - 初始化
170+
- (void)_setup{
171+
self.tableView.rowHeight = 55;
172+
self.title = @"Example17";
173+
}
174+
175+
#pragma mark - 设置导航栏
176+
- (void)_setupNavigationItem{
177+
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(_shuffle:)];
178+
}
179+
180+
#pragma mark - 设置子控件
181+
- (void)_setupSubViews{
182+
183+
}
184+
185+
#pragma mark - 布局子控件
186+
- (void)_makeSubViewsConstraints{
187+
188+
}
189+
190+
#pragma mark - Setter & Getter
191+
192+
@end

‎MHDevelopExample/MHDevelopExample/Architecture/MainFrame/MainFrame/CMHMainFrameViewController.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ - (void)viewDidLoad {
7070

7171
/// 布局子空间
7272
[self _makeSubViewsConstraints];
73+
7374
}
7475
#pragma mark - Override
7576
- (UIEdgeInsets)contentInset{
Binary file not shown.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /