前言:
从DKMeituanHD项目中体会了真正的MVC思想:视图不依赖于具体的数据类型,而是依赖于遵守特定协议的数据源。M 和V 是不存在依赖关系。就行UIKit 中的UItableview一样,什么样的数据M,UItableview都可以展示,只要M遵守实现了UITableViewDataSource协议。
本文的例子:
M遵守的数据源协议: DKHomeDropdownViewDataSource
V:DKHomeDropdownView.h 具体看本文的附
正文
V 对数据源M使用协议进行规范
/**
*真正的MVC思想:视图不依赖于具体的数据类型,而是依赖于遵守特定协议的数据源。
M 和V 是不存在依赖关系。就行UIKit 中的UItableview一样,什么样的数据M都可以展示。
V 提供一套数据源协议(代理),向外界索要数据。即向数据源对象增加一套统一的协议方法,来规范数据源对象
ps: 而非容易想到的,将数据通过属性直接提供给V。这样会导致数据源的单一性
*/
视图的数据直接向数据源对象请求,而不是从自身属性获取。
例子:
在美团app 中要实现两个样式一样,展示的数据不一样的下拉菜单。
此时为了代码的抽取,利用上述思想进行实现。
分析:
1、首页的下拉菜单,由两个tableview组成,即 主表和从表。因此采用两个UITableView实现。因此需要对主从表展示的数据进行约束抽象出DKHomeDropdownViewData 协议。
2、在自定义视图下拉菜单DKHomeDropdownView 实现的UITableView 协议方法中分别处理主从数据,而数据直接向数据源对象请求。因此下拉菜单需要DKHomeDropdownViewDataSource 协议属性。
3、DKHomeDropdownView 内部发生了选择事件的时候,需要通知外围的控制器,因此需要DKHomeDropdownViewDelegate代理属性。
DKHomeDropdownView 的头文件请见附。
DKHomeDropdownView 的实现细节请参考DKMeituanHD。
附
DKHomeDropdownView.h
//
// DKHomeDropdownView.h
// DKMeituanHD
//
// Created by devzkn on 07/01/2017.
// Copyright © 2017 hisun. All rights reserved.
//
#import <UIKit/UIKit.h>
@class DKHomeDropdownView;
@protocol DKHomeDropdownViewDelegate <NSObject>
@optional
- (void)homeDropdownView:(DKHomeDropdownView*)homeDropdownView didSelectedRowsInMainTable:(NSInteger)row;
- (void)homeDropdownView:(DKHomeDropdownView*)homeDropdownView didSelectedRowsInSubTable:(NSInteger)row inMainTable:(NSInteger)mainRow;;
@end
@protocol DKHomeDropdownViewData <NSObject>
@required
- (NSString*) title;
- (NSArray*)subdata;
@optional
- (NSString*)icon;
- (NSString*)selectedIcon;
@end
@protocol DKHomeDropdownViewDataSource <NSObject>
@required
/**
左边的表格一共有多少行。
@param homeDropdownView 下拉菜单
@return 行数
*/
- (NSInteger)numberOfRowsInMainTableDKHomeDropdownView:(DKHomeDropdownView*)homeDropdownView;
- (id<DKHomeDropdownViewData>) homeDropdownView:(DKHomeDropdownView*)homeDropdownView subdataForRowsInMainTable:(NSInteger)row;
@end
/**
*首页的下拉菜单,由两个tableview组成
*/
@interface DKHomeDropdownView : UIView
/**
*真正的MVC思想:
M 和V 是不存在依赖关系。就行UIKit 中的UItableview一样,什么样的数据M都可以展示。
V 提供一套数据源协议(代理),向外界索要数据。即向数据源对象增加一套统一的协议方法,来规范数据源对象
ps: 而非容易想到的,将数据通过属性直接提供给V。这样会导致数据源的单一性
*/
@property (nonatomic,assign) id<DKHomeDropdownViewDataSource> dataSource;
@property (nonatomic,assign) id<DKHomeDropdownViewDelegate> delegate;
+ (instancetype) homeDropdownView;
- (void) reloadData;
@end