iOS开发总结 - 下载图片并浏览(UICollectionView)
昨天根据贴图库api做的一个浏览图片的Demo, 源码在这: https://github.com/beddup/TieTuKuBrowers
总结如下:
1. AFNetworking 的使用
demo中通过http api 下载数据,数据有json和image,所以使用了AFHTTPSessionManager (基于NSURLSession)
AFNetworking非常方便,可以直接将json转换为NSArray/ NSDictionary, 将image data转换为 UIImage, 前提是正确设置好responseSerializer(否则error)。
responseSerializer用来将数据转换为正确的类型:
- 默认的responseSerializer为AFJSONResponseSerializer (使用iOS自带的JSON解析工具),此外还有:
- AFXMLParserResponseSerializer: 解析XML
-AFXMLDocumentResponseSerializer
-AFPropertyListResponseSerializer
-AFImageResponseSerializer
-以及AFCompoundResponseSerializer (将多个AFHTTPResponseSerializer 组合,因为demo的数据由json,也有image,所以使用就是这个responseSerializer)
AFHTTPSessionManager的简单用法(get),
- 创建实例,可用- initWithBaseURL:(nullable NSURL *)url,BaseURL即http地址中靠前的一部分
- 如有必要设置 responseSerializer
- 进行http 请求,以get为例
1 - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString 2 // URLString: 与base url 共同组成请求的http url 资源。 3 parameters:(nullable id)parameters 4 5 success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success 6 // 获取成功后调用的block,responseObject是已经转换好的数据,如NSArray, UIImage 7 failure:(nullable void (^)(NSURLSessionDataTask *task, NSError *error))failure;
方法返回NSURLSessionDataTask, 有时需要这个,比如之后可能需要取消task。
2. UICollectionView & Cell
- UIColletionView 与 UITableView 类似, datasource 和 delegate 方法基本一致
- UIColletionView delegate 中没有设置section header 和 section footer 的方法,但可用
(UICollectionReusableView *)collectionView:viewForSupplementaryElementOfKind: atIndexPath:代替
- 自定义cell ,最好重写 prepareForReuse 方法,UIColletionView 在dequeue cell 时,会调用该方法,然后才将cell 返回。
prepareForReuse方法主要用来重置cell的状态 ,如果不重置cell的状态,dequeue返回的cell内容可能时之前dequeue cell的内容
- table view 有tableheader 和tablefooter,collectionview中没有对应的属性和方法,如何设置呢? (hint: 用contentInset)
3. Core Data
- Xcode 7 中为entity生成NSManagedObject时,将自动生成一个NSManagedObject子类和一个CoreDataProperties category 更加方便
4. Objective-C 和 Swift 混编
- 在Swift中使用Objective-C, 需要一个Objective-C Bridging header, 在该 .h 中import 需要使用的Objective-C 类
- 在Objective-C中使用Swift,需要一个Objective-C Generated Interface Header, xcode 7 自动生成,且bunble中不显示,使用将该文件import到Objective-C file
- 在target building setting中swift complier code generation 可看到或更改这两个文件的名称。
- 对此,这个博文http://blog.csdn.net/mmoaay/article/details/48422309 说明的很好
5. 加载网络资源同时,如何使UICollectionView更流畅
- 加载某网络资源后,随后对应的cell 滚出 屏幕,此时不必要再加载,应取消节省内存
- 应适当缓存获取的资源。
- 如果资源获取到之后,应判断对应的cell 是否可见,若不可见,缓存资源,若可见,用cellForItemAtIndexPath获取cell (不应该直接使用方法的cell,否则cell 不释放,占用内存)
- 如果cell内容复杂,render耗时,可先异步draw 静态部分,然后生成一个image 添加到cell中。可用NSOperationQueue管理复杂任务,当对应的cell 滚出屏幕时,应取消该任务
- 对此,wwdc的这个视频 Building Concurrent User Interfaces-WWDC2011 讲的很好
6. 如 5 所述,可用 NSOperationQueue 管理复杂耗时的内容,必要时取消该任务
7. 在UICollectionView 实现 pull to refresh (上拉加载更多)思路
- 在viewDidLayoutSubviews中将refresh view 的位置设置在UICollectionView内容的最下面, 不在contentsize范围内
- 在scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
a. 根据contentOffset判断是否需要加载更多(在这过程可对refresh view动画)
b. 若需要加载更多,设置 contentInset 为UIEdgeInsetsMake(0, 0, bottom, 0),bottom的值应 > refresh view的高度。这样UICollectionView将不再scroll,并显示refresh view, 这时加载资源
c. 资源加载完毕之后,将contentInset 设置为 UIEdgeInsetsZero, 并增加contentOffset 使部分新加载的资源可见