GitHub recommended a Swift blank page display library. In line with the good use of wheels, improve productivity principle, download the source code to see, share with you.

When we use the App, we often display a blank page in the App to prompt users to perform operations due to unsuccessful requests or data errors. Prompt contents include: 1. Picture, 2. Title, 3. In this library, the prompt content is contained in EmptyStateView.

EmptyStateView

This view defines what to display and what to do with the blank page. Internally, a ViewModel is defined to display the content. EmptyStateView follows NibLoadable, which allows instance objects to be created by loading from Nib.

Struct ViewModel {var image: UIImage? var title: String? var description: String? var titleButton: String? } var viewModel =ViewModel() {didSet {fillView()}} var format =EmptyStateFormat{didSet {updateUI()}} var actionButton: ((UIButton)->())?Copy the code

EmptyState

To use the library, we just need to set the emptyState.delegate and emptyState.dataSource of the view, so that the proxy object follows EmptyStateDelegate and EmptyStateDataSource. You can call the show and Hide methods to show and Hide blank pages.

view.emptyState.delegate = self
view.emptyState.dataSource = self

Copy the code

So, how does the emptyState of a view come into being? The author uses the association object here to dynamically associate the EmptyState instance to the EmptyState of the view.

enum ViewAssociatedKeys {
    static var emptyState = "emptyState"
}

public extension UIView {
    
    var emptyState: EmptyState! {
        get {
            guard let saved = ao_get(pkey: &ViewAssociatedKeys.emptyState) as? EmptyState else {
                self.emptyState = EmptyState(inView: self)
                return self.emptyState
            }
            return saved
        }
        set { ao_set(newValue ?? EmptyState(inView: self), pkey: &ViewAssociatedKeys.emptyState) }
    }
}

Copy the code

EmptyState is a class that manages the display and hiding of blank pages. When an instance of this class is created, an instance of EmptyStateView is created and displayed according to the view (UITableView/UICollectionView) in which the empty page is to be displayed. Blank pages in UITableView/UICollectionView are set directly to their background view.

init(inView view: UIView?) {// Create a blank page emptyStateView = emptyStateview.view emptyStateview.ishidden =true
    emptyStateView.actionButton = { [weak self] (button) inself? .didPressActionButton(button)} // Add to the view to display a blank pageif let view = view as? UITableView {
        view.backgroundView = emptyStateView
        tableView = view
        separatorStyle = view.separatorStyle
    } else if let view = view as? UICollectionView {
        view.backgroundView = emptyStateView
    } else {
        emptyStateView.fixConstraintsInView(view)
    }
}

Copy the code

The response event for the action is passed to EmptyState’s didPressActionButton() via EmptyStateView’s actionButton, and then to EmptyStateDelegate’s EmptyState () () (), The handling of events is handed over to proxy objects.

Customize the display – CustomState

If you want a blank page to display a different image/title/prompt, write an Enum, following CustomState, and return the image/title/description/titileButton that follows CustomState. Returns an instance of EmptyStateFormat. An instance of EmptyStateView updates the display based on the format attribute.

//EmptyStateView's format property. Setting its value updates ui.var format =EmptyStateFormat() {
    didSet { updateUI() }
}

Copy the code

The author has an example to look at.

enum TableState: CustomState {
    
    case noNotifications
    case noBox
    case noCart
    case noFavorites
    case noLocation
    case noProfile
    case noSearch
    case noTags
    case noInternet
    case noIncome
    case inviteFriend
    
    var image: UIImage? {
        switch self {
        case .noNotifications: return UIImage(named: "Messages")
        case .noBox: return UIImage(named: "Box")
        case .noCart: return UIImage(named: "Cart")
        case .noFavorites: return UIImage(named: "Favorites")
        case .noLocation: return UIImage(named: "Location")
        case .noProfile: return UIImage(named: "Profile")
        case .noSearch: return UIImage(named: "Search")
        case .noTags: return UIImage(named: "Tags")
        case .noInternet: return UIImage(named: "Internet")
        case .noIncome: return UIImage(named: "Income")
        case .inviteFriend: return UIImage(named: "Invite")
        }
    }
    
    var title: String? {
        switch self {
        case .noNotifications: return "No message notifications"
        case .noBox: return "The box is empty"
        case .noCart: return "The cart is empty"
        case .noFavorites: return "No favorites"
        case .noLocation:  return "Where are you?"
        case .noProfile: return "Not logged In"
        case .noSearch: return "No results"
        case .noTags: return "No collections"
        case .noInternet: return "We 're Sorry." "
        case .noIncome: return "No income"
        case .inviteFriend: return "Ask friend!"
        }
    }
    
    var description: String? {
        switch self {
        case .noNotifications: return "Sorry, you don't have any message. Please come back later!"
        case .noBox: return "You dont have any email!"
        case .noCart: return "Please, select almost one item to purchase"
        case .noFavorites: return "Select your favorite items first!"
        case .noLocation: return "We can't find your location"
        case .noProfile: return "Please register or log in first"
        case .noSearch: return "Please try another search item"
        case .noTags: return "Go to collect favorites products"
        case .noInternet: return "Our staff is still working on the issue for better experience"
        case .noIncome: return "You have no payment so contact your client"
        case .inviteFriend: return "You could borrow money from your network"
        }
    }
    
    var titleButton: String? {
        switch self {
        case .noNotifications: return "Search again?"
        case .noBox: return "Search again?"
        case .noCart: return "Go back"
        case .noFavorites: return "Go back"
        case .noLocation: return "Locate now!"
        case .noProfile: return "Log in now!"
        case .noSearch: return "Go back"
        case .noTags: return "Go shopping"
        case .noInternet: return "Try again?"
        case .noIncome: return "Request payment"
        case .inviteFriend: return "View contact"}}}Copy the code

You can also use EmptyStateDataSource to return the content to be displayed in the corresponding state.

link

EmptyStateKit:github.com/alberdev/Em…