EmptyPage(空白页组件)原理与使用

栏目: IOS · 发布时间: 6年前

内容简介:app 显示列表内容时, 在某一时刻可能数据为空(等待网络请求/网络请求失败)等, 添加一个空白指示页将有效缓解用户可能造成的焦虑或混乱. 并可以帮助用户处理问题.市面上已经有部分成熟的空白页框架,最典型的就是使用但是其使用

app 显示列表内容时, 在某一时刻可能数据为空(等待网络请求/网络请求失败)等, 添加一个空白指示页将有效缓解用户可能造成的焦虑或混乱. 并可以帮助用户处理问题.

市面上已经有部分成熟的空白页框架,最典型的就是使用 DZNEmptyDataSet .

但是其使用 DZNEmptyDataSetDelegate , DZNEmptyDataSetSource 来定制空白页元素,使用时较为繁琐.

笔者借鉴其原理的基础上,制作了对标框架(单向对标) EmptyPage 来简化日常项目开发.

前言

EmptyPage 历时1年, 在我司项目中稳定使用迭代6个版本,算是比较稳定.

支持UICollectionView & UITableView.

ps: 目前阶段只提供 swift 版本.

EmptyPage(空白页组件)原理与使用
EmptyPage(空白页组件)原理与使用

实现原理

该核心部分 作为一个单独的子库 实现, 可使用 以下方式单独引用.

pod 'EmptyPage/Core'
复制代码

具体代码可查阅 Github Link , 超级简单.

  1. UIScrollView 添加 emptyView 对象作为空白页实例:

    public extension UIScrollView {
      public var emptyView: UIView?
    }
    复制代码
  2. Method Swizzling 方式替换掉 UITableView \ UICollectionView 中部分相关函数.以下拿 UITableView 举例:

    // DZNEmptyDataSet 对 autolayout 项目不太友好. (也可能本人没深度使用...)
    // EmptyPage 
    // UITableView frame 变化相关函数
    open func layoutSubviews()
    open func layoutIfNeeded()
    // 数据源增减相关函数
    open func insertRows(at indexPaths: [IndexPath], with animation: UITableView.RowAnimation)
    open func deleteRows(at indexPaths: [IndexPath], with animation: UITableView.RowAnimation)
    open func insertSections(_ sections: IndexSet, with animation: UITableView.RowAnimation)
    open func deleteSections(_ sections: IndexSet, with animation: UITableView.RowAnimation)
    open func reloadData()
    复制代码
  3. 在数据/frame变化时判断空白页显示与隐藏.

    func setEmptyView(event: () -> ()) {
        oldEmptyView?.removeFromSuperview()
        event()
        guard bounds.width != 0, bounds.height != 0 else { return }
        var isHasRows = false
        let sectionCount = dataSource?.numberOfSections?(in: self) ?? numberOfSections
        for index in 0..<sectionCount {
          if numberOfRows(inSection: index) > 0 {
            isHasRows = true
            break
          }
        }
        isScrollEnabled = isHasRows
        if isHasRows {
          emptyView?.removeFromSuperview()
          return
        }
        guard let view = emptyView else{ return }
        view.frame = bounds
        addSubview(view)
        sendSubview(toBack: view)
      }
    复制代码
  4. 使用

    UITableView().emptyView = CustomView()
    UICollectionView().emptyView = CustomView()
    复制代码

    UITableView().emptyView 第一次被赋值时才会进行 Method Swizzling 相关函数.

模板视图

DZNEmptyDataSet 的成功离不开其可高度定制化的模板视图.但其繁琐的 delegate apis 远不如自定义视图来的方便, 其对自定义视图的支持也并不友善.

EmptyPage 优先支持 自定义视图,并附赠 3 套可以凑合看的模板视图(支持超级高自定义调节,但毕竟UI我们说了不算...)

采用 以下方式 则包含该部分内容:

pod 'EmptyPage'
复制代码
  1. 自定义视图

    • 仅支持autolayout布局模式

      不使用 autolayout 模式:

      pod 'EmptyPage/Core'
      UITableView().emptyView = CustomView()
      
    • 自定义视图需要autolayout实现自适应高

      可以参考 内置的几套模板视图的约束实现.

    • 添加 EmptyPageContentViewProtocol 协议

      该协议默认实现了将自定义视图居中约束至一个 backgroundView 上.

      通用性考虑: backgroundView.frame 与 tableView.frame 相同

      示例:

      class CustomView: EmptyPageContentViewProtocol{
          ...
      }
      
      let customView = CustomView()
      UITableView().emptyView = customView.mix()
      复制代码

      不添加该协议,可采用以下方式:

      UITableView().emptyView = EmptyPageView.mix(view: customView)

    • 视图关系

      EmptyPage(空白页组件)原理与使用
  2. 内置模板视图

    **特性: **

    1. 支持链式调用.
    2. 元素支持高度自定义.
    3. 同样依照自定义视图的标准实现.

    ps: 完全等同于提前写好的自定义模板视图.

    • 目前可以选择3套基本的模板视图.
      • 文字模板( EmptyPageView.ContentView.onlyText )

      • 图片模板( EmptyPageView.ContentView.onlyImage )

      • 混合模板( EmptyPageView.ContentView.standard )

    EmptyPage(空白页组件)原理与使用
    EmptyPage(空白页组件)原理与使用
    EmptyPage(空白页组件)原理与使用
    • 使用

      • 示例:

        UITableView().emptyView = EmptyPageView.ContentView.standard
        	.change(hspace: .button, value: 80)
        	.change(height: .button, value: 60)
        	.change(hspace: .image, value: 15)
        	.config(button: { (item) in
        		item.backgroundColor = UIColor.blue
        		item.contentEdgeInsets = UIEdgeInsets(top: 8, left: 20, bottom: 8, right: 20)
        	})
        	.set(image: UIImage(named: "empty-1002")!)
        	.set(title: "Connection failure", color: UIColor.black, font: UIFont.boldSystemFont(ofSize: 24))
        	.set(text: "Something has gone wrong with the internet connection. Let's give it another shot.", color: UIColor.black, font: UIFont.systemFont(ofSize: 15))
        	.set(buttonTitle: "TRY AGAIN")
        	.set(tap: {
        	// 点击事件
        	})
        	.mix()
        复制代码
    • Apis

      模板视图中总结起来只有三种配置函数:

      • 约束配置函数: func change(...) -> Self

        约束函数具体可配置项采用枚举的形式限定.(以免改变/冲突自适应高度相关约束)

        enum HSpaceType { } // 修改视图水平方向上的间距

        enum VSpaceType { } // 修改视图垂直方向上的间距

        enum HeightType { } // 修改视图具体高度

        例如:

        standardView.change(hspace: .button, value: 80)
        			.change(height: .button, value: 60)
        复制代码
      • 控件配置函数: func set(...) -> Self

        提供了简单的文本/字体/图片/颜色配置.例如:

        standardView.set(title: "Connection failure", color: UIColor.black, font: UIFont.boldSystemFont(ofSize: 24))
        复制代码
      • 控件自定义配置函数: func config(element: { (element) in ... }) -> Self

        返回一个完整的控件,可供深度配置. 例如:

        standardView.config(button: { (item) in
        	item.backgroundColor = UIColor.blue
        	item.contentEdgeInsets = UIEdgeInsets(top: 8, left: 20, bottom: 8, right: 20)
        	})
        复制代码
      • 视图混合函数 func mix() :

        该函数由 EmptyPageContentViewProtocol 协议默认实现.

        作用: 将视图约束至 backgroundView 上

        ps: 别忘了...


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Web Designer's Idea Book

The Web Designer's Idea Book

Patrick Mcneil / How / 2008-10-6 / USD 25.00

The Web Designer's Idea Book includes more than 700 websites arranged thematically, so you can find inspiration for layout, color, style and more. Author Patrick McNeil has cataloged more than 5,000 s......一起来看看 《The Web Designer's Idea Book》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具