FFFramework的实现
来源:互联网 发布:淘宝的外贸原单 编辑:程序博客网 时间:2024/06/07 10:42
前言
最近,结合公司的项目,在前人的基础上整理了一个Framework的一个东西,主要包含了一些常用的category
整理; model
基类的使用,基于MJExtension
实现一个model
基类,模型数据的使用可以继承该基类;网络请求的使用,对于 AFNetworking
的封装,可实现数据请求和网络下载;第三方分享的封装,可以直接使用,分享到QQ,微信, 微博;View的一些使用,1)UITableView和UICollectionView的封装使用,实现UITableView和UICollectionView的上拉刷新和下拉加载(PS:不是三方的刷新和加载)2)自定义的TabBar;UIViewController的使用,实现一个基类的ViewController,实现相关的属性设置,VC的使用继承该基类;还有一些帮助类的使用。FFFramework暂不支持Cocopods。
项目结构介绍
具体使用
- Category
Category里面主要是一些常用分类,比如设备类型,文件管理,日期设置,颜色处理和图片处理等,没什么值得具体说的,具体用的时候直接拿来用就可以了。附张图看一眼吧:
- Models
Model里面会有一个叫做FFBaseModel
的基类,凡是关于模型数据的都可以集成该基类。如图:
用法也很简单,是基于MJExtension
,和 MIExtension
的使用是一致的,只不过在外层包装了一下而已。支持字典转模型,字典数组转模型数组, 模型数组转字典数组等。下面是一些常用方法:
@interface FFBaseModel : NSObject- (NSDictionary *)ff_toKeyValue;- (void)ff_modelsDidFinishConvertingToKeyValues;- (void)ff_keyvaluesDidFinishConvertingToModels;// 属性名替换 + (NSDictionary *)ff_replaceKeyFromPropertyName;+ (NSDictionary *)ff_objectClassInArray;// 可忽略的属性名+ (NSArray *)ff_ignoredPropertyNames;// 字典转模型+ (instancetype)ff_modelFromKeyValue:(NSDictionary *)keyValue;+ (NSArray *)ff_keyValuesFromModels:(NSArray *)models;// 字典数组转模型数组+ (NSArray *)ff_modelsFromKeyValues:(NSArray *)keyvalues;+ (NSArray *)ff_allowedCodingPropertyNames;+ (NSArray *)ff_ignoredCodingPropertyNames;@end
- Network
Network里面包含网络数据的请求和上传,以及网络数据下载,基于AFNetworking
对AFNetworking
的封装使用,包括 FFBaseRequest
和 FFBaseDownloadRequest
, 如下:
1) 先看 FFBaseRequest.h
文件
#import <UIKit/UIKit.h>#import <Foundation/Foundation.h>@class FFBaseRequest;typedef NS_ENUM(NSUInteger, FFRequestMethod) { FFRequestMethodGet, FFRequestMethodPost, FFRequestMethodPut, FFRequestMethodDelete};typedef NS_ENUM(NSInteger, FFNetworkReachabilityStatus) { FFNetworkReachabilityStatusUnknown = -1, FFNetworkReachabilityStatusNotReachable = 0, FFNetworkReachabilityStatusReachableViaWWAN = 1, FFNetworkReachabilityStatusReachableViaWiFi = 2,};typedef NS_ENUM(NSUInteger, FFRequestError) { FFRequestErrorNetwork = 0};static NSString *Key_Model = @"Key_Model";typedef void(^reqSuccessBlock)(FFBaseRequest *request);typedef void(^reqCancelBlock)(FFBaseRequest *request);typedef void(^reqFailureBlock)(FFBaseRequest *request, NSError *error);typedef void(^reqUploadBlock)(FFBaseRequest *request, NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite);@interface FFBaseRequest : NSObject/**请求路径*/@property (nonatomic, copy, readonly) NSString *requestUrl;/**请求参数*/@property (nonatomic, strong, readonly) NSDictionary *requestParameters;/**上传二进制数据数组*/@property (nonatomic, strong, readonly) NSMutableArray *binaryParameterArray;/**返回字典数据*/@property (nonatomic, strong, readonly) NSMutableDictionary *resultDict;/**结果数组*/@property (nonatomic, strong, readonly) NSMutableArray *resultArray;/**结果字符串*/@property (nonatomic, copy) NSString *resultString;@property (nonatomic, strong, readonly) UIImage *responseImage;/**是否请求成功*/@property (nonatomic, assign, readonly) BOOL isSuccess;/** * 网络数据请求 * * @param parameters 上传参数 * @param successBlock 成功回调 * @param cancelBlock 取消回调 * @param failureBlock 失败回调 */+ (void)requestParameters:(NSDictionary *)parameters successBlock:(reqSuccessBlock)successBlock cancelBlock:(reqCancelBlock)cancelBlock failureBlock:(reqFailureBlock)failureBlock;/** * 执行请求 * * @param parameters 请求参数(非二进制文件) * @param binaryArray 上传的二进制文件(ZZBinaryData对象) * @param successBlock 成功回调 * @param cancelBlock 取消回调 * @param failureBlock 失败回调 * @param uploadProcessBlock 上传进度回调 */+ (void)requestParameters:(NSDictionary *)parameters binaryArray:(NSMutableArray *)binaryArray successBlock:(reqSuccessBlock)successBlock cancelBlock:(reqCancelBlock)cancelBlock failureBlock:(reqFailureBlock)failureBlock uplodProcessBlock:(reqUploadBlock)uploadProcessBlock;/**获取请求地址*/- (NSString *)getRequestUrl;/// 是否正在请求数据+ (BOOL)isRequesting;/**获取当前网络类型*/+ (FFNetworkReachabilityStatus)fetchReachabilityStatus;/**启动网络监听*/+ (void)starNetWorkReachability;#pragma mark - Children Class- (NSString *)getRequestHost;- (NSString *)getRequestQuery;- (NSString *)getUserAgent;/**请求头设置*/- (NSDictionary<NSString *, NSString *> *)getCustomHeaders;/**请求方式(默认GET)*/- (FFRequestMethod)getRequestMethod;/**请求参数*/- (NSDictionary *)getDefaultParameters;/**数据解析*/- (void)processResult;/**取消请求*/+ (void)cancelTheRequest;#pragma mark- 以下可根据服务器返回自行设置/**是否成功*/- (BOOL)success;/**请求失败错误信息*/- (NSString *)errorMsg;/**数据总数*/- (NSInteger)totalCount;/**是否有数据(通常是分页请求数据)*/- (BOOL)hasMoreData;@end
已有相关的注释,具体查看可以看源项目, 我会在最后把地址贴一下,现在结合一个接口, 看一下具体使用,一般数据请求和UITableView连用,我一起贴出来了:
首先,继承FFBaseRequest
创建一个通用请求类 TestRequest
#import "FFBaseRequest.h"extern NSString * const FORMAL_SERVER_URL;extern NSString * const TEST_SERVER_URL;@interface TestRequest : FFBaseRequest@end/*******************************************/#import "TestRequest.h"// 以豆瓣的接口为例NSString * const FORMAL_SERVER_URL = @"https://api.douban.com/v2/"; // 正式服务器NSString * const TEST_SERVER_URL = @"https://api.douban.com/v2/"; // 测试服务器@implementation TestRequest#pragma mark - Methods// 设置getRequestHost的目的是为了方便,如:https://api.douban.com/v2/book/search?q=“美女”&start = 0&count = 20 这个地址,https://api.douban.com/v2/ 这是通用的,可单独提取出来,如针对图书相关的接口,将book/search?q=“美女”&start = 0&count = 20拼起来即可。- (NSString *)getRequestHost { return FORMAL_SERVER_URL; // return TEST_SERVER_URL;}- (BOOL)isSuccess { return [self success];}- (BOOL)success { if ([self.resultDict.allKeys containsObject:@"status"]) { NSDictionary *dict = self.resultDict[@"status"]; NSInteger code = [[NSString stringWithFormat:@"%@", dict[@"code"]] integerValue]; return code == 1; } return false;}- (NSString *)errorMsg { if ([self.resultDict.allKeys containsObject:@"status"]) { NSDictionary *dict = self.resultDict[@"status"]; return dict[@"msg"]; } return @"";}#pragma mark - 可根据具体返回数据设置相关属性- (NSInteger)totalCount { return [self.resultDict[@"total"] integerValue];}@end
接着,以豆瓣的图书搜索为例,继承 TestRequest
创建一个图书搜索请求 TestARequest
/** 获取书籍信息的接口 *//**GET https://api.douban.com/v2/book/search参数 意义 备注q 查询关键字 q和tag必传其一tag 查询的tag q和tag必传其一start 取结果的offset 默认为0count 取结果的条数 默认为20,最大为100返回:返回status=200,{ "start": 0, "count": 10, "total": 30, "books" : [Book, ]}*/#import "TestRequest.h"@interface TestARequest : TestRequest@end/*******************************************/#import "TestARequest.h"#import "TestModel.h" // 图书模型@implementation TestARequest// https://api.douban.com/v2/book/search?q=“美女”&start = 0&count = 20, https://api.douban.com/v2/ 已提取出来, 由于q=“美女”&start = 0&count = 20中 q ,start, count 可能会有改变,故不能写死, 在 getRequestQuery方法中拼接book/search? 即可。 - (NSString *)getRequestQuery { return @"book/search?";}// 进行数据解析,字典数组转模型- (void)processResult { NSArray *results = self.resultDict[@"books"]; NSArray *books = [TestModel ff_modelsFromKeyValues:results]; if (books != nil) { [self.resultDict setObject:books forKey:Key_Model]; }}
准备工作已完成,下面就在ViewController里面请求数据:
// 下拉刷新和上拉加载可先忽略- (void)getNetData:(BOOL)isRefresh { if ([TestARequest isRequesting]) { return; } __weak typeof(self) WS = self; NSInteger page = isRefresh ? 1 : _page + 1; NSDictionary *parameter = @{@"q": @"美女", @"start": @(page), @"count": @20}; // 1.设置下拉刷新 (不需要的话可去掉) id refreshBlock = ^{ [WS getNetData:YES]; }; [self.tableView setRefreshBlock:refreshBlock]; // 回调成功Block id successBlock = ^(FFBaseRequest *request){ NSLog(@"请求路径-->> %@",request.requestUrl); // 这时请求路径就是一个完成的地址了。 NSLog(@"请求参数-->> %@",request.requestParameters); NSLog(@"请求结果-->> %@",request.resultDict); // 2.设置分页数 _page = page; // 3.获取数据 NSArray *arrResult = request.resultDict[Key_Model]; if (isRefresh) { WS.books = arrResult; } else { NSMutableArray *arrTemp = [NSMutableArray arrayWithArray:WS.books]; [arrTemp addObjectsFromArray:WS.books]; WS.books = arrTemp; } // 4.设置上拉加载(不需要可去掉) id moreBlock = ^ { [WS getNetData:NO]; }; [WS.tableView setMoreBlock:request.totalCount > WS.books.count ? moreBlock : nil]; // 5.完成加载 [WS.tableView didFinishedLoading]; // 6.数据刷新 [WS.tableView reloadData]; }; // 回调取消Block id cancleBlock = ^(FFBaseRequest *request) { [WS.tableView didFinishedLoading]; }; // 回调失败Block id failureBlock = ^(FFBaseRequest *request, NSError *error){ [WS.tableView didFinishedLoading]; NSLog(@"---> %@",error.localizedDescription); }; [TestARequest requestParameters:parameter successBlock:successBlock cancelBlock:cancleBlock failureBlock:failureBlock];}
到此,一个数据请求就算完成了,这样更加模块化,更加好维护。。。。
2) 接着看FFBaseDownloadRequest.h
#import <Foundation/Foundation.h>@class FFBaseDownloadRequest;extern NSString * const FFDownloadErrorReasonKey;extern NSString * const FFDownloadDoDownloadBlockKey;extern NSString * const FFDownloadAllowUseMobileNetworkKey;extern NSString * const FFDownloadAllowUseMobileNetworkNotification;typedef void(^ProgressBlock)(float progress, NSUInteger bytesRead, unsigned long long totalRead, unsigned long long totalExpectedToRead);typedef void(^SuccessBlock)(FFBaseDownloadRequest *request, id responseObject);typedef void(^CancelBlock)(FFBaseDownloadRequest *request);typedef void(^FailureBlock)(FFBaseDownloadRequest *request, NSError *error);@interface FFBaseDownloadRequest : NSObject/** * 下载路径(文件夹) */@property (nonatomic, strong, readonly) NSString *downloadPath;@property (nonatomic, strong, readonly) NSString *fileName;/** * 下载文件绝对路径 */@property (nonatomic, strong, readonly) NSString *filePath;/** * 下载文件 * * @param URLStirng 文件链接 * @param fileName 文件名 * @param progressBlock 下载进度回调 * @param successBlock 下载成功回调 * @param failureBlock 下载失败回调 * * @return 下载任务 */+ (FFBaseDownloadRequest *)downloadFileWithURLString:(NSString *)URLStirng fileName:(NSString *)fileName progressBlock:(ProgressBlock)progressBlock successBlock:(SuccessBlock)successBlock cancelBlock:(CancelBlock)cancelBlock failureBlock:(FailureBlock)failureBlock;/** * 下载文件 * * @param URLStirng 文件链接 * @param fileName 文件名 * @param downloadPath 下载位置 * @param progressBlock 下载进度回调 * @param successBlock 下载成功回调 * @param failureBlock 下载失败回调 * * @return 下载任务 */+ (FFBaseDownloadRequest *)downloadFileWithURLString:(NSString *)URLStirng downloadPath:(NSString *)downloadPath fileName:(NSString *)fileName progressBlock:(ProgressBlock)progressBlock successBlock:(SuccessBlock)successBlock cancelBlock:(CancelBlock)cancelBlock failureBlock:(FailureBlock)failureBlock;/** * 暂停下载文件 * * @param downloadRequest 下载任务 */+ (void)pauseWithDownloadRequest:(FFBaseDownloadRequest *)downloadRequest;/** * 恢复下载文件 * * @param downloadRequest 下载请求 */+ (void)resumeWithDownloadRequest:(FFBaseDownloadRequest *)downloadRequest;/** * 获取文件大小 * * @param path 本地路径 * * @return 文件大小 */- (unsigned long long)fileSizeForPath:(NSString *)path;/** * 暂停下载 */- (void)pauseDownload;/** * 恢复下载 */- (void)resumeDownload;/** * 取消下载 */- (void)cancelDownload;/** * 是否正在下载 */- (BOOL)isDownloading;/** * 是否完成 */- (BOOL)finished;/** * 移除Cache */+ (void)removeAllCache;
网络数据下载,简单使用 :
- (void)downloadData { // http://dldir1.qq.com/qqfile/QQforMac/QQ_V5.5.1.dmg NSString *path = [kCachePath stringByAppendingPathComponent:@"QQ"]; if (![NSFileManager isDirectoryExist:path]) { [NSFileManager createDirectorysAtPath:path]; } [FFBaseDownloadRequest downloadFileWithURLString:@"http://dldir1.qq.com/qqfile/QQforMac/QQ_V5.5.1.dmg" downloadPath:path fileName:[NSString stringWithFormat:@"%@", @"1.zip"] progressBlock:^(float progress, NSUInteger bytesRead, unsigned long long totalRead, unsigned long long totalExpectedToRead) { NSLog(@"---------->> %f", progress); } successBlock:^(FFBaseDownloadRequest *request, id responseObject) { NSLog(@">> %@",request.filePath); } cancelBlock:^(FFBaseDownloadRequest *request) { } failureBlock:^(FFBaseDownloadRequest *request, NSError *error) { NSLog(@" ---->> %@",error.localizedDescription); }];}
- ShareKit
ShareKit里面包含分享都QQ,微信,微博 第三方平台,傻瓜式分享,只需要申请相对应的AppKey 和 AppSecretKey,设置好相关的白名单,就能实现分享啦~~。
下面我们来看看简单使用: ShareContentInfo
类设置分享信息,包含分享的类型(文字,链接等)
#import "FFBaseModel.h"#import "FFAuthInfo.h"typedef NS_ENUM(NSUInteger, ShareContentType) { ShareContentType_None, ShareContentType_Text, ShareContentType_Link, ShareContentType_Image};@interface ShareContentInfo : FFBaseModel@property (nonatomic, strong) NSString *title;@property (nonatomic, strong) NSString *content;@property (nonatomic, strong) NSString *urlStr;@property (nonatomic, strong) NSString *imgPath;@property (nonatomic, strong) NSData *objData;@property (nonatomic, assign) ShareContentType contentType;@property (nonatomic, assign) ShareType shareType;/** * 获取分享信息 * * @param title 标题 * @param content 内容 * @param contentType 分享的类型 * @return ShareContentInfo */+ (instancetype)shareTitle:(NSString *)title content:(NSString *)content contentType:(ShareContentType)contentType;/** * 获取分享信息 * * @param title 标题 * @param content 内容 * @param url 链接 * @param imgPath 图片地址 * @param contentType 分享的类型 * @return ShareContentInfo */+ (instancetype)shareTitle:(NSString *)title content:(NSString *)content url:(NSString *)url imagePath:(NSString *)imgPath contentType:(ShareContentType)contentType;/** * 获取分享信息 * * @param title 标题 * @param content 内容 * @param url 链接 * @param imgPath 图片地址 * @param objData 图片二进制文件 * @param contentType 分享的类型 * @return ShareContentInfo */+ (instancetype)shareTitle:(NSString *)title content:(NSString *)content url:(NSString *)url imagePath:(NSString *)imgPath objData:(NSData *)objData contentType:(ShareContentType)contentType;
FFBaseShareCenter
类设置分享:
typedef void(^ShareSuccessBlock)();typedef void(^ShareCancelBlock)(BOOL cancelled);typedef void(^ShareFailureBlock)(NSError *error);typedef NS_ENUM(NSUInteger, InstallClientType) { InstallClientType_None, InstallClientType_QQ, InstallClientType_QZone, InstallClientType_Both_QQ_QZone, InstallClientType_Weibo, InstallClientType_WeChat};typedef enum : NSUInteger { SourceAppTypeUnknow, SourceAppTypeQQ, SourceAppTypeWX, SourceAppTypeWB,} SourceAppType;extern NSString * const ErrorDescKey;extern NSString * const QQAppIdKey;extern NSString * const SinaAppIdKey;extern NSString * const SinaRedirectURIKey;extern NSString * const WeChatAppIdKey;extern NSString * const WeChatAppSecretKey;@interface FFBaseShareCenter : NSObject@property (nonatomic, strong) FFUser *user;@property (nonatomic, strong) FFAuthInfo *authInfo;@property (nonatomic, strong, readonly) NSDictionary *AppIdDict;@property (nonatomic, assign, readonly, getter=isInstalledClient) InstallClientType installedClient;- (void)openClientAuthWithShareType:(ShareType)shareType successBlock:(ShareSuccessBlock)shareSuccessBlock cancelBlock:(ShareCancelBlock)shareCancelBlock failureBlock:(ShareFailureBlock)shareFailureBlock;+ (SourceAppType)sourceAppTypeWithSourceAppString:(NSString *)sourceApplication;/** 在appDelegate,- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 里面实现该方法 */+ (BOOL)handlerOpenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication;/** * 设置各平台的AppId、AppSecret、RedirectURI * * @param appIdDict key 为QQAppIdKey,SinaAppIdKey,WeChatAppIdKey value 为各平台AppId * @param appSecretDict key 为WeChatAppSecretKey,... value为各平台的Secret * @param redirectURIDict key 为SinaRedirectURIKey,... value为各平台的RedirectURI */+ (void)setAppId:(NSDictionary *)appIdDict appSecret:(NSDictionary *)appSecretDict redirectURI:(NSDictionary *)redirectURIDict;/** * 获取分享平台 * * @param shareType 分享类型 * @return 分享平台 */+ (FFBaseShareCenter *)getShareCenterWithShareType:(ShareType)shareType;/** * 分享 * * @param contentInfo 分享信息 * @param successBlock 成功回调 * @param cancelBlock 取消回调 * @param failureBlock 失败回调 */- (void)shareContentInfo:(ShareContentInfo *)contentInfo successBlock:(ShareSuccessBlock)successBlock cancelBlock:(ShareCancelBlock)cancelBlock failureBlock:(ShareFailureBlock)failureBlock;- (void)executeFailureBlock:(ShareFailureBlock)failureBlock errorDomain:(NSString *)ErrorDomain errorMsg:(NSString *)errorMsg errorCode:(NSInteger)errorCode;
简单使用,如下:
- (IBAction)onShareBtnTap:(UIButton *)sender { UIImage *image = [UIImage imageNamed:@"benz.png"]; NSData *imgData = UIImagePNGRepresentation(image); ShareContentInfo *shareInfo = [ShareContentInfo shareTitle:@"哈哈哈" content:@"你在干什么,什么都不说" url:@"https:www.baidu.com" imagePath:nil objData:imgData contentType:ShareContentType_Link]; ShareType shareType = ShareType_None; if (sender.tag == 1) { shareType = ShareType_WeChat; } else if (sender.tag == 2) { shareType = ShareType_QQ; } else if (sender.tag == 3) { shareType = ShareType_WeChatTimeline; } else if (sender.tag == 4) { shareType = ShareType_Sina; } shareInfo.shareType = shareType; FFBaseShareCenter *shareCenter = [FFBaseShareCenter getShareCenterWithShareType:shareType]; [shareCenter shareContentInfo:shareInfo successBlock:^{ NSLog(@"分享成功"); } cancelBlock:^(BOOL cancelled) { NSLog(@"取消分享"); } failureBlock:^(NSError *error) { NSLog(@"分享失败 --->%@",error.localizedDescription); }];}
- ViewController
ViewController创建了一个基类,使用VC的时候都可以继承该基类,可设置标题,NavigationBar的设置, 如下:
@interface FFBaseViewController : UIViewController/**设置标题*/@property (nonatomic, copy) NSString *navigationTitle;/**设置标题颜色*/@property (nonatomic, strong) UIColor *navigationTitleColor;/**设置NavigationBar颜色*/@property (nonatomic, strong) UIColor *navigationBarColor;/**隐藏NavigationBar*/@property (nonatomic, assign, getter=isHideNavigationBar) BOOL hideNavigationBar;/**隐藏状态栏*/@property (nonatomic, assign, getter=isHideStatusBar) BOOL hideStatusBar;/**设置状态栏样式*/@property (nonatomic, assign, getter=isStatusBarStyleDefault) BOOL statusBarStyleDefault;@property (nonatomic, assign, getter=isNavBarColorChange) BOOL navBarColorChange;/**左按钮*/@property (nonatomic, strong) UIButton *leftBtn;/**右按钮*/@property (nonatomic, strong) UIButton *rightBtn;/**右边多个按钮数组*/@property (nonatomic, strong) NSArray *rightBtns;/***/@property (nonatomic, copy) DismissBlock dismissBlock;/**显示返回按钮(默认返回按钮)*/- (void)showBackBtn;/**返回按钮点击*/- (void)onBackBtnTap:(UIButton *)sender;/**取消请求*/- (void)cancelAllRequest;+ (NSString *)classStr;
- View
View里面包含自定义 UITableView
和 UICollectionView
的使用,内封装下拉刷新和上拉加载的使用。
上面介绍了UITableView的使用,包括下拉刷新和上拉加载,这里介绍一下UICollectionView的使用。
- (void)getRequest:(BOOL) isRefresh { if ([TestARequest isRequesting]) { return; } __weak typeof(self) WS = self; NSInteger page = isRefresh ? 1 : _page + 1; NSDictionary *parameter = @{@"q": @"美女", @"start": @(page), @"count": @10}; // 回调成功Block id successBlock = ^(FFBaseRequest *request){ // 设置分页数 _page = page; // 获取数据 NSArray *arrResult = request.resultDict[Key_Model]; if (isRefresh) { WS.books = arrResult; } else { NSMutableArray *arrTemp = [NSMutableArray arrayWithArray:WS.books]; [arrTemp addObjectsFromArray:WS.books]; WS.books = arrTemp; } // 设置上拉加载 [WS.collectionView isDisplayMoreView:WS.books.count < request.totalCount]; // 完成加载 [WS.collectionView didFinishedLoading]; // 刷新数据 [WS.collectionView reloadData]; }; // 回调取消Block id cancleBlock = ^(FFBaseRequest *request) { [WS.collectionView didFinishedLoading]; }; // 回调失败Block id failureBlock = ^(FFBaseRequest *request, NSError *error){ [WS.collectionView didFinishedLoading]; }; [TestARequest requestParameters:parameter successBlock:successBlock cancelBlock:cancleBlock failureBlock:failureBlock];}// 需要实现的两个协议方法#pragma mark - FFCollectionViewDelegate- (void)collectionViewLoadMore:(FFCollectionView *)collectionView { [self getRequest:NO];}- (void)collectionViewRefresh:(FFCollectionView *)collectionView { [self getRequest:YES];}
结语
到这里,基本上FFFramework的基本使用算是差不多了,具体的详细使用可以把源项目下载下来具体的试验一下。洋洋洒洒的写了这一些,算是一种总结归纳吧。。。 希望在总结的同时对别人也能有帮助。 另外, 附上源项目的地址: https://github.com/ismilesky/FFDemo.git
未完待续, 会持续补充。。。。。
- FFFramework的实现
- 三子棋的实现的实现的实现
- JAVA实现的时钟实现
- 模态框的的实现
- 杀毒软件的简单实现的简单实现
- android的实现电话号码的实现
- 音频的实现音乐声音的实现
- malloc的实现、内存池的实现
- 异形窗体的实现
- 个性化的分页实现
- ASP数据库连接的实现
- Struts单选框的实现
- 梅西迭代算法的实现
- 翻页功能的实现
- Struts,MVC 的实现
- 实现JavaScript的继承
- 接口的显示实现
- TTerm的实现( 一)
- css颜色渐变效果
- 欢迎使用CSDN-markdown编辑器
- Window.open()方法
- 避免滥用单例
- 混合背包
- FFFramework的实现
- windows下用bat命令自动设置ip地址和dns
- iOS网络HTTP、TCP、UDP、Socket 知识总结
- 深度学习(四) yolov2转换到Qt环境下编译
- Java线程面试题 Top 50
- 常用SQL语言
- stm32gpio寄存器小小心得
- 剪邮票 蓝桥杯
- 电缆建设