6 单图缓存+刷新

  • 单张图片缓存思路
    先把图片缓存到本地,再获取图片大小 (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 参数用于判断是上啦还是下拉

你可能感兴趣的:(6 单图缓存+刷新)