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 861669e

Browse files
1. 新增 CMHTableViewController 和 CMHCollectionViewController 使用的示例程序
1. 新增 CMHTableViewController 使用的示例程序 2. 新增 CMHCollectionViewController 使用的示例程序 3. 增加了一个左对齐布局 以及 瀑布流的布局 第三方框架
1 parent 655aade commit 861669e

File tree

128 files changed

+5824
-81
lines changed

Some content is hidden

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

128 files changed

+5824
-81
lines changed

‎MHDevelopExample/.DS_Store

0 Bytes
Binary file not shown.

‎MHDevelopExample/MHDevelopExample.xcodeproj/project.pbxproj

Lines changed: 452 additions & 0 deletions
Large diffs are not rendered by default.

‎MHDevelopExample/MHDevelopExample/AppDelegate.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
6161

6262
[self.window makeKeyAndVisible];
6363

64+
65+
6466
#if defined(DEBUG)||defined(_DEBUG)
6567
// [self _configDebugModelTools];
6668
#endif
@@ -76,6 +78,9 @@ - (void)_configureApplication:(UIApplication *)application initialParamsBeforeIn
7678

7779
/// 配置键盘
7880
[self _configureKeyboardManager];
81+
82+
// 配置YYWebImage
83+
[self _configureYYWebImage];
7984
}
8085

8186
/// 配置键盘管理器
@@ -85,6 +90,13 @@ - (void)_configureKeyboardManager {
8590
IQKeyboardManager.sharedManager.shouldResignOnTouchOutside = YES;
8691
}
8792

93+
/// 配置YYWebImage
94+
- (void)_configureYYWebImage {
95+
/// CoderMikeHe Fixed Bug : 解决 SDWebImage & YYWebImage 加载不出http://img3.imgtn.bdimg.com/it/u=965183317,1784857244&fm=27&gp=0.jpg的BUG
96+
NSMutableDictionary *header = [YYWebImageManager sharedManager].headers.mutableCopy;
97+
header[@"User-Agent"] = @"iPhone";
98+
[YYWebImageManager sharedManager].headers = header;
99+
}
88100

89101
#pragma mark - 调试(DEBUG)模式
90102
- (void)_configDebugModelTools{
0 Bytes
Binary file not shown.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// CMHCollectionViewCell.h
3+
// MHDevelopExample
4+
//
5+
// Created by lx on 2018年6月11日.
6+
// Copyright © 2018年 CoderMikeHe. All rights reserved.
7+
//
8+
9+
#import <UIKit/UIKit.h>
10+
11+
@interface CMHCollectionViewCell : UICollectionViewCell
12+
13+
@end
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// CMHCollectionViewCell.m
3+
// MHDevelopExample
4+
//
5+
// Created by lx on 2018年6月11日.
6+
// Copyright © 2018年 CoderMikeHe. All rights reserved.
7+
//
8+
9+
#import "CMHCollectionViewCell.h"
10+
11+
@implementation CMHCollectionViewCell
12+
13+
@end
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//
2+
// CMHCollectionViewController.h
3+
// MHDevelopExample
4+
//
5+
// Created by lx on 2018年6月11日.
6+
// Copyright © 2018年 CoderMikeHe. All rights reserved.
7+
// CMHCollectionViewController 跟 CMHTableViewViewController 使用类似
8+
9+
#import "CMHViewController.h"
10+
11+
@interface CMHCollectionViewController : CMHViewController<UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout>
12+
13+
/// The table view for collectionView controller.
14+
/// tableView
15+
@property (nonatomic, readonly, weak) UICollectionView *collectionView;
16+
/// collectionView 的布局,默认是 `UICollectionViewFlowLayout`
17+
@property (nonatomic, readwrite, strong) UICollectionViewLayout *collectionViewLayout;
18+
/// The data source of table view
19+
@property (nonatomic, readonly, strong) NSMutableArray *dataSource;
20+
21+
/// `collectionView` 的内容缩进,default is UIEdgeInsetsMake(64,0,0,0),you can override it
22+
@property (nonatomic, readonly, assign) UIEdgeInsets contentInset;
23+
24+
// 滚动方向 default is UICollectionViewScrollDirectionVertical
25+
@property (nonatomic, readwrite, assign) UICollectionViewScrollDirection scrollDirection;
26+
27+
/// 需要支持下来刷新 defalut is NO
28+
@property (nonatomic, readwrite, assign) BOOL shouldPullDownToRefresh;
29+
/// 是否默认开启自动刷新, YES : 系统会自动调用`collectionViewDidTriggerHeaderRefresh` NO : 开发人员手动调用 `collectionViewDidTriggerHeaderRefresh`
30+
@property (nonatomic, readwrite, assign) BOOL shouldBeginRefreshing;
31+
/// 需要支持上拉加载 defalut is NO
32+
@property (nonatomic, readwrite, assign) BOOL shouldPullUpToLoadMore;
33+
/// 是否数据是多段 (It's effect collectionView's dataSource 'numberOfSectionsInTableView:') defalut is NO
34+
@property (nonatomic, readwrite, assign) BOOL shouldMultiSections;
35+
/// 是否在上拉加载后的数据,dataSource.count < pageSize 提示没有更多的数据.default is YES 默认做法是数据不够时,隐藏mj_footer
36+
@property (nonatomic, readwrite, assign) BOOL shouldEndRefreshingWithNoMoreData;
37+
38+
/// 当前页 defalut is 1
39+
@property (nonatomic, readwrite, assign) NSUInteger page;
40+
/// 每一页的数据 defalut is 20
41+
@property (nonatomic, readwrite, assign) NSUInteger perPage;
42+
43+
44+
/// sub class can override 且 不需要调用 [super ....]
45+
/// reload tableView data , sub class can override
46+
- (void)reloadData;
47+
48+
/// equeueReusableCell
49+
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
50+
51+
/// configure cell data
52+
- (void)configureCell:(UICollectionViewCell *)cell atIndexPath:(NSIndexPath *)indexPath withObject:(id)object;
53+
54+
/// 下拉刷新事件
55+
- (void)collectionViewDidTriggerHeaderRefresh;
56+
/// 上拉加载事件
57+
- (void)collectionViewDidTriggerFooterRefresh;
58+
///brief 加载结束 这个方法 子类只需要在 `collectionViewDidTriggerHeaderRefresh`和`collectionViewDidTriggerFooterRefresh` 结束刷新状态的时候直接调用即可,不需要重写,当然如果不喜欢内部的处理逻辑,你直接重写即可
59+
///discussion 加载结束后,通过参数reload来判断是否需要调用collectionView的reloadData,判断isHeader来停止加载
60+
///param isHeader 是否结束下拉加载(或者上拉加载)
61+
///param reload 是否需要重载TabeleView
62+
///
63+
- (void)collectionViewDidFinishTriggerHeader:(BOOL)isHeader reload:(BOOL)reload;
64+
65+
@end
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
//
2+
// CMHCollectionViewController.m
3+
// MHDevelopExample
4+
//
5+
// Created by lx on 2018年6月11日.
6+
// Copyright © 2018年 CoderMikeHe. All rights reserved.
7+
//
8+
9+
#import "CMHCollectionViewController.h"
10+
11+
@interface CMHCollectionViewController ()
12+
/// collectionView
13+
@property (nonatomic , readwrite , weak) UICollectionView *collectionView;
14+
/// contentInset defaul is (64 , 0 , 0 , 0)
15+
@property (nonatomic, readwrite, assign) UIEdgeInsets contentInset;
16+
/// 数据源
17+
@property (nonatomic, readwrite, strong) NSMutableArray *dataSource;
18+
@end
19+
20+
@implementation CMHCollectionViewController
21+
22+
- (void)dealloc{
23+
// set nil
24+
_collectionView.dataSource = nil;
25+
_collectionView.delegate = nil;
26+
}
27+
28+
29+
- (instancetype)init{
30+
if (self = [super init]) {
31+
_scrollDirection = UICollectionViewScrollDirectionVertical;
32+
_shouldBeginRefreshing = YES;
33+
_page = 1;
34+
_perPage = 20;
35+
_shouldEndRefreshingWithNoMoreData = YES;
36+
}
37+
return self;
38+
}
39+
40+
41+
- (void)viewDidLoad{
42+
[super viewDidLoad];
43+
// 设置子控件
44+
[self _su_setupSubViews];
45+
}
46+
47+
48+
#pragma mark - Override
49+
- (void)configure
50+
{
51+
[super configure];
52+
53+
/// observe viewModel's dataSource
54+
55+
}
56+
57+
#pragma mark - 设置子控件
58+
/// setup add `_su_` avoid sub class override it
59+
- (void)_su_setupSubViews{
60+
61+
/// UICollectionViewFlowLayout + UICollectionView
62+
if (self.collectionViewLayout == nil) {
63+
UICollectionViewFlowLayout *flowLayout = [UICollectionViewFlowLayout new];
64+
flowLayout.scrollDirection = self.scrollDirection;
65+
self.collectionViewLayout = flowLayout;
66+
}
67+
68+
/// CollectionView
69+
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:self.collectionViewLayout];
70+
collectionView.backgroundColor = [UIColor whiteColor];
71+
collectionView.delegate = self;
72+
collectionView.dataSource = self;
73+
self.collectionView = collectionView;
74+
[self.view addSubview:collectionView];
75+
76+
/// 设置显示区域
77+
collectionView.contentInset = self.contentInset;
78+
79+
/// 注册cell
80+
[collectionView registerClass:UICollectionViewCell.class forCellWithReuseIdentifier:@"UICollectionViewCell"];
81+
82+
/// 添加加载和刷新控件
83+
if (self.shouldPullDownToRefresh) {
84+
/// 下拉刷新
85+
@weakify(self);
86+
[self.collectionView mh_addHeaderRefresh:^(MJRefreshHeader *header) {
87+
/// 加载下拉刷新的数据
88+
@strongify(self);
89+
[self collectionViewDidTriggerHeaderRefresh];
90+
}];
91+
if (self.shouldBeginRefreshing) {
92+
[self.collectionView.mj_header beginRefreshing];
93+
}
94+
}
95+
96+
if (self.shouldPullUpToLoadMore) {
97+
/// 上拉加载
98+
@weakify(self);
99+
[self.collectionView mh_addFooterRefresh:^(MJRefreshFooter *footer) {
100+
/// 加载上拉刷新的数据
101+
@strongify(self);
102+
[self collectionViewDidTriggerFooterRefresh];
103+
}];
104+
105+
/// CoderMikeHe Fixed Bug : 这里先隐藏,防止一进来用户看到上拉加载控件,影响美观
106+
self.collectionView.mj_footer.hidden = YES;
107+
}
108+
109+
#ifdef __IPHONE_11_0
110+
/// CoderMikeHe: 适配 iPhone X + iOS 11,
111+
MHAdjustsScrollViewInsets_Never(collectionView);
112+
#endif
113+
114+
}
115+
116+
#pragma mark - 上下拉刷新事件
117+
/// 下拉事件
118+
- (void)collectionViewDidTriggerHeaderRefresh{
119+
/// subclass override it
120+
[self collectionViewDidFinishTriggerHeader:YES reload:NO];
121+
}
122+
123+
/// 上拉事件
124+
- (void)collectionViewDidTriggerFooterRefresh{
125+
/// subclass override it
126+
[self collectionViewDidFinishTriggerHeader:NO reload:NO];
127+
}
128+
129+
/// 结束刷新
130+
- (void)collectionViewDidFinishTriggerHeader:(BOOL)isHeader reload:(BOOL)reload{
131+
__weak typeof(self) weakSelf = self;
132+
dispatch_async(dispatch_get_main_queue(), ^{
133+
__strong typeof(weakSelf) strongSelf = weakSelf;
134+
if (reload) {
135+
[strongSelf.collectionView reloadData];
136+
}
137+
if (isHeader) {
138+
/// 重置没有更多的状态
139+
if (self.shouldEndRefreshingWithNoMoreData){
140+
[self.collectionView.mj_footer setHidden:NO];
141+
[self.collectionView.mj_footer resetNoMoreData];
142+
}else{
143+
[self.collectionView.mj_footer setHidden:NO];
144+
}
145+
[strongSelf.collectionView.mj_header endRefreshing];
146+
}
147+
else{
148+
[strongSelf.collectionView.mj_footer endRefreshing];
149+
}
150+
151+
/// 这里可以用来显示隐藏 mj_footer
152+
[self _requestDataCompleted];
153+
154+
});
155+
}
156+
157+
- (void)_requestDataCompleted{
158+
159+
NSUInteger count = self.dataSource.count;
160+
/// CoderMikeHe Fixed: 这里必须要等到,底部控件结束刷新后,再来设置无更多数据,否则被叠加无效
161+
if (self.shouldMultiSections) return; // 多组的不处理
162+
163+
if (count == 0 || count % self.perPage) {
164+
165+
if (self.shouldEndRefreshingWithNoMoreData) {
166+
[self.collectionView.mj_footer endRefreshingWithNoMoreData];
167+
}else{
168+
self.collectionView.mj_footer.hidden = YES;
169+
}
170+
}
171+
}
172+
173+
174+
175+
#pragma mark - sub class can override it
176+
- (UIEdgeInsets)contentInset{
177+
return UIEdgeInsetsMake(MH_APPLICATION_TOP_BAR_HEIGHT, 0, 0, 0);
178+
}
179+
180+
/// reload tableView data
181+
- (void)reloadData{
182+
[self.collectionView reloadData];
183+
}
184+
185+
/// dequeueReusable Cell
186+
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath {
187+
return [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
188+
}
189+
190+
/// configure cell data
191+
- (void)configureCell:(UICollectionViewCell *)cell atIndexPath:(NSIndexPath *)indexPath withObject:(id)object {}
192+
193+
194+
#pragma mark - UICollectionViewDataSource&UICollectionViewDelegate
195+
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
196+
if (self.shouldMultiSections) return self.dataSource ? self.dataSource.count : 0;
197+
return 1;
198+
}
199+
200+
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
201+
if (self.shouldMultiSections) {
202+
NSArray *subDataSource = self.dataSource[section];
203+
return subDataSource.count;
204+
}
205+
return self.dataSource.count;
206+
}
207+
208+
209+
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
210+
UICollectionViewCell *cell = [self collectionView:collectionView dequeueReusableCellWithIdentifier:@"UICollectionViewCell" forIndexPath:indexPath];
211+
// fetch object
212+
id object = nil;
213+
if (self.shouldMultiSections) object = self.dataSource[indexPath.section][indexPath.item];
214+
if (!self.shouldMultiSections) object = self.dataSource[indexPath.item];
215+
216+
/// bind model
217+
[self configureCell:cell atIndexPath:indexPath withObject:(id)object];
218+
return cell;
219+
220+
}
221+
222+
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
223+
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
224+
}
225+
226+
227+
#pragma mark - Setter & Getter
228+
- (NSMutableArray *)dataSource{
229+
if (_dataSource == nil) {
230+
_dataSource = [[NSMutableArray alloc] init];
231+
}
232+
return _dataSource ;
233+
}
234+
235+
- (void)setShouldPullDownToRefresh:(BOOL)shouldPullDownToRefresh{
236+
if (_shouldPullDownToRefresh != shouldPullDownToRefresh) {
237+
_shouldPullDownToRefresh = shouldPullDownToRefresh;
238+
if (_shouldPullDownToRefresh) {
239+
@weakify(self);
240+
[self.collectionView cmh_addHeaderRefresh:^(MJRefreshHeader *header) {
241+
/// 加载下拉刷新的数据
242+
@strongify(self);
243+
[self collectionViewDidTriggerHeaderRefresh];
244+
}];
245+
}else{
246+
self.collectionView.mj_header = nil;
247+
}
248+
}
249+
}
250+
251+
- (void)setShouldPullUpToLoadMore:(BOOL)shouldPullUpToLoadMore{
252+
if (_shouldPullUpToLoadMore != shouldPullUpToLoadMore) {
253+
_shouldPullUpToLoadMore = shouldPullUpToLoadMore;
254+
if (_shouldPullUpToLoadMore) {
255+
/// 上拉加载
256+
@weakify(self);
257+
[self.collectionView cmh_addFooterRefresh:^(MJRefreshFooter *footer) {
258+
/// 加载上拉刷新的数据
259+
@strongify(self);
260+
[self collectionViewDidTriggerFooterRefresh];
261+
}];
262+
}else{
263+
self.collectionView.mj_footer = nil;
264+
}
265+
}
266+
}
267+
268+
@end

0 commit comments

Comments
(0)

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