-
单张图片缓存思路
先把图片缓存到本地,再获取图片大小 (GCD调度组监听下载完成) -
单张图片缓存
进入加载微博列表视图 以前因为没有刷新所以一个数组就够了,但是现在因为需要上拉和下拉 所以需要新创建一个数组 把第一次加载的数据先放到临时数组 再拼接到显示列表数组
// 2. 字典转模型
// 定义并且创建一个临时数组,记录当前网络请求返回的结果
var arrayM = AnyObject// 遍历数组,字典转模型 for dict in array { arrayM.append(StatusViewModel(status: Status(dict: dict))) } //把临时数组拼接到显示列表数组 self?.statuses += arrayM
遍历出只有1张图片的
private func cacheWebImage(array: [StatusViewModel]) {
// 遍历视图模型数组
for viewModel in array {
// 目标:只需要缓存单张图片
let count = viewModel.thumbnailURLs?.count ?? 0
if count != 1 {
continue
}
printLog(viewModel.thumbnailURLs)
- 闭包回调
在异步 闭包当成参数回调
SDWEB核心下载
// 2. 入组 - 紧贴着 block/闭包,enter & leave 要配对出现
dispatch_group_enter(group)
// 使用 SDWebImage 的核心函数下载图片
SDWebImageManager.sharedManager().downloadImageWithURL(viewModel.thumbnailURLs![0], options: [], progress: nil, completed: { (image, _, _, _, _) in
// 代码执行到此,图片已经缓存完成,不一定有 image
if image != nil {
// 将 image 转换成二进制数据
let data = UIImagePNGRepresentation(image)
dataLength += data?.length ?? 0
}
// 3. 出组 - block 的最后一句
dispatch_group_leave(group)
})
}
// 4. 调度组监听
dispatch_group_notify(group, dispatch_get_main_queue()) {
printLog("缓存图像完成 \(dataLength / 1024) K")
// 执行闭包
finished()
}
非尾随闭包
self?.cacheWebImage(arrayM as! [StatusViewModel],finish()->()){}
尾随闭包
self?.cacheWebImage(arrayM as! [StatusViewModel]) {
//开始执行闭包内的操作
self?.statuses += arrayM
// 3. 通知调用方数据加载完成
subscriber.sendCompleted()
}
在闭包中发送rac completed 让home控制器的订阅者 刷新表格
-
设置单图的宽高
在pictureView 中设置单张图片高度
判断图片是否被正确的缓存
并且防止极端过宽过窄的图if count == 0 { return CGSizeZero } // 2> 1张图 if count == 1 { var size = CGSize(width: 150, height: 150) // 判断图片是否已经被正确的缓存 Key 是 URL 的完整字符串 let key = statusViewModel!.thumbnailURLs![0].absoluteString // 如果有缓存图片,记录当前图片的大小 if let image = SDWebImageManager.sharedManager().imageCache.imageFromDiskCacheForKey(key) { size = image.size } // 单独处理过宽或者过窄的图片 size.width = size.width < 40 ? 40 : size.width size.width = size.width > 300 ? 300 : size.width layout.itemSize = size return size }
面试:sbwebimage缓存的图片名是怎么命名的?
MD5加密的
-
图片填充模式
-
tableviewcell指定背景颜色 (默认是nil) 可以优化性能 减少渲染时间(因为默认是透明的 与底层颜色合并渲染会消耗更多地时间/不用clearColor和alpha)
-
刷新
在homeViewController中
tableview默认有refreshControl
可以创建一个
refreshControl = UIRefreshControl()
UIControl都有addTarget 监听事件用valueChange
// 准备下拉刷新控件 - 刷新控件的高度是 60 点
refreshControl = HMRefreshControl()
refreshControl?.addTarget(self, action: "loadData", forControlEvents: UIControlEvents.ValueChanged)
beginRefreshing endRefreshing
/// 加载数据
func loadData() {
// beginRefreshing只会播放刷新动画,不会加载数据
refreshControl?.beginRefreshing()
statusListViewModel.loadStatuses().subscribeNext({ (result) -> Void in
// TODO:
}, error: { (error) -> Void in
// 关闭刷新控件
self.refreshControl?.endRefreshing()
printLog(error)
SVProgressHUD.showInfoWithStatus("您的网络不给力")
}) {
// 关闭刷新控件
self.refreshControl?.endRefreshing()
// 刷新表格
self.tableView.reloadData()
}
- 自定义刷新控件
创建xib
/// 刷新视图,单独负责显示内容&动画
class HMRefreshView: UIView {
/// 负责从 XIB 加载视图
class func refreshView() -> HMRefreshView {
return NSBundle.mainBundle().loadNibNamed("HMRefreshView", owner: nil, options: nil).last! as! HMRefreshView
}
在refreshController中创建刷新view
private func setupUI() {
// 隐藏转轮
tintColor = UIColor.clearColor()
addSubview(refreshView)
// 自动布局 - 从 XIB 加载的视图会保留 XIB 中指定的大小
refreshView.ff_AlignInner(type: ff_AlignType.CenterCenter, referView: self, size: refreshView.bounds.size)
}
// MARK: - 懒加载控件
private lazy var refreshView = HMRefreshView.refreshView()
- 下拉提示图标动画(小针改变方向)
KVO监听frame改变
监听方法:
observerValueForKeyPath
向下偏移量超过-60 改变箭头方向
旋转动画 BLock 动画 默认顺时针 就近原则
小技巧:微调旋转角度 +0.01 - 加载数据刷新动画
防止动画重复加载 - 上拉刷新
tableview.tableFootview上加 activity indicator 记得要startAnimating哦 不然不会显示
思路:tableview cellforrow中 判断是否是最后一个cell
index.row ==statuscount && 没在播放控件动画
- 上啦&下拉数据实现
网络方法内 loadStatus
拼接数据
上拉:在网络方法内 增加ispullrefresh 参数用于判断是上啦还是下拉
网友评论