When the app displays the list contents, the data may be empty at a certain moment (waiting for network request/network request failure), etc., adding a blank indicating page will effectively relieve the anxiety or confusion caused by users. And can help users deal with problems.

There are some mature blank page frameworks in the market, the most typical of which is using DZNEmptyDataSet.

But its use DZNEmptyDataSetDelegate DZNEmptyDataSetSource to customize the blank page elements, use more complicated.

On the basis of its principle, the author made a benchmarking framework (one-way benchmarking)EmptyPage to simplify the daily project development.

preface

EmptyPage lasted for one year and has been used for 6 iterations in our project, which is relatively stable.

Support UICollectionView & UITableView.

Ps: Only swift version is available at this stage.

Realize the principle of

This core part is implemented as a separate sublibrary and can be referenced separately in the following ways.

pod 'EmptyPage/Core'
Copy the code

Specific code can be consulted Github Link, super simple.

  1. forUIScrollViewaddemptyViewObject as a blank page instance:
    public extension UIScrollView {
      public var emptyView: UIView?
    }
    Copy the code
  2. Method SwizzlingWay to replaceUITableView \ UICollectionViewPart of the correlation function. The following takeUITableViewFor example:
    DZNEmptyDataSet is not very friendly to autolayout project.
    // EmptyPage 
    // UITableView frame changes related functions
    open func layoutSubviews(a)
    open func layoutIfNeeded(a)
    // Add or subtract related functions from the data source
    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(a)
    Copy the code
  3. Determine whether blank pages are displayed or hidden when data /frame changes.
    func setEmptyView(event: (a)-> ()) { oldEmptyView? .removeFromSuperview() event()guardbounds.width ! =0, bounds.height ! =0 else { return }
        var isHasRows = false
        letsectionCount = dataSource? .numberOfSections? (in: self)?? numberOfSectionsfor index in 0..<sectionCount {
          if numberOfRows(inSection: index) > 0 {
            isHasRows = true
            break
          }
        }
        isScrollEnabled = isHasRows
        ifisHasRows { emptyView? .removeFromSuperview()return
        }
        guard let view = emptyView else{ return }
        view.frame = bounds
        addSubview(view)
        sendSubview(toBack: view)
      }
    Copy the code
  4. use

    UITableView().emptyView = CustomView(a)UICollectionView().emptyView = CustomView(a)Copy the code

    UITableView().emptyView is first assigned to Method Swizzling.

The template view

DZNEmptyDataSet’s success depends on its highly customizable template view. But its cumbersome delegate apis aren’t nearly as convenient as custom views, and its support for custom views isn’t exactly friendly.

EmptyPage supports custom views in preference to EmptyPage, and comes with 3 sets of template views that work just fine.

This section is included in the following ways:

pod 'EmptyPage'
Copy the code
  1. Custom view
    • Only the Autolayout layout mode is supported

      Not using Autolayout mode:

      1. pod 'EmptyPage/Core'

      2. UITableView().emptyView = CustomView()

    • Custom views require autolayout to achieve high adaptive

      You can refer to the constraint implementations of several built-in template views.

    • Add EmptyPageContentViewProtocol agreement

      By default, the protocol centers a custom view onto a backgroundView.

      Commonality considerations: BackgroundView. frame is the same as tableView.frame

      Example:

      class CustomView: EmptyPageContentViewProtocol{... }let customView = CustomView(a)UITableView().emptyView = customView.mix()
      Copy the code

      You can use either of the following methods to not add the protocol:

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

    • View relationship

  2. Built-in Template view

    ** Features: **

    1. Support for chain calls.
    2. Element supports a high degree of customization.
    3. The same is true for custom views.

    Ps: Exactly equivalent to a custom template view written in advance.

    • You can currently choose from three sets of basic template views.
      • Text template (EmptyPageView.ContentView.onlyText)
      • Image template(EmptyPageView.ContentView.onlyImage)
      • Mixed template (EmptyPageView.ContentView.standard)
  • use

    • Example:

      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: {
      	// Click the event
      	})
      	.mix()
      Copy the code
  • Apis

    There are only three configuration functions summed up in the template view:

    • Constraint configuration function: func change(…) -> Self

      The specific configurable terms of the constraint function are qualified in the form of enumerations (to avoid changing/conflicting adaptive highly dependent constraints).

      Enum HSpaceType {} // Modify the horizontal spacing of views

      Enum VSpaceType {} // Modifies the vertical spacing of views

      Enum HeightType {} // Changes the view height

      Such as:

      standardView.change(hspace: .button, value: 80)
      			.change(height: .button, value: 60)
      Copy the code
    • Control configuration function: func set(…) -> Self

      Simple text/font/image/color configurations are provided. Such as:

      standardView.set(title: "Connection failure", color: UIColor.black, font: UIFont.boldSystemFont(ofSize: 24))
      Copy the code
    • Func config(Element: {(element) in… }) -> Self

      Returns a complete control that can be configured in depth. Such as:

      standardView.config(button: { (item) in
      	item.backgroundColor = UIColor.blue
      	item.contentEdgeInsets = UIEdgeInsets(top: 8.left: 20, bottom: 8.right: 20)})Copy the code
    • Func mix():

      This function by EmptyPageContentViewProtocol default implementation agreement.

      Effect: Binds a view to backgroundView

      Ps: Don’t forget…

At the end

Project open source link: Github/EmptyPage

Personal blog link: Foursquare