分享一個輪子 - 空白頁庫【Swift】

今看到GitHub推薦了個Swift的空白頁展現庫;本着善用輪子,提升生產力的原則,下載了源碼看了下,分享給你們。git

咱們在使用App的時候,常常會出現由於請求不成功 / 數據錯誤等緣由,在應用中顯示一個空白頁,提示用戶進行操做。提示的內容包括:1.圖片, 2.標題,3.提示正文,4.操做按鈕。在這個庫,中這些提示內容都包含在EmptyStateView裏。github

EmptyStateView

這個視圖定義了空白頁要顯示的內容以及操做。內部定義了一個ViewModel來顯示內容。EmptyStateView遵循NibLoadableNibLoadable是讓實例對象從Nib中加載建立。bash

//視圖內容
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)->())?

複製代碼

EmptyState

在使用這個庫的時候,咱們只須要設置viewemptyState.delegateemptyState.dataSource,讓代理對象遵循EmptyStateDelegateEmptyStateDataSource,就能夠調用showHide方法顯示與隱藏空白頁。ide

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

複製代碼

那麼,viewemptyState是怎麼出現的?做者在這裏使用了關聯對象,動態的將EmptyState實例關聯給viewemptyStateui

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) }
    }
}

複製代碼

EmptyState是一個類,管理空白頁的顯示與隱藏。在這個類的實例建立的時候,就一併建立了EmptyStateView的實例,而且根據要顯示空白頁的視圖(UITableView / UICollectionView)來顯示,UITableView / UICollectionView裏空白頁都是直接設置爲其背景視圖spa

init(inView view: UIView?) {
    
    // 建立空白頁
    emptyStateView = EmptyStateView.view
    emptyStateView.isHidden = true
    emptyStateView.actionButton = { [weak self] (button) in
        self?.didPressActionButton(button)
    }
    
    // 添加到要顯示空白頁的視圖
    if 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)
    }
}

複製代碼

操做的響應事件,經過EmptyStateViewactionButton,傳遞給EmptyStatedidPressActionButton(),再傳遞到了EmptyStateDelegateemptyState()()(),將事件的處理交由了代理對象處理。代理

定製化顯示 - CustomState

想要空白頁顯示不一樣的圖片 / 標題 / 提示語,寫個Enum,遵循CustomState,再由對應枚舉值,返回遵循CustomState,要實現的image / title / description / titileButton,返回EmptyStateFormat的實例。EmptyStateView的實例會根據format屬性,更新顯示內容。code

//EmptyStateView的format屬性,設置其值,會更新UI.
var format = EmptyStateFormat() {
    didSet { updateUI() }
}

複製代碼

做者有個示例能夠看下。orm

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"
        }
    }
}

複製代碼

固然也能夠經過EmptyStateDataSource返回對應狀態下要顯示的內容。cdn

連接

EmptyStateKit:github.com/alberdev/Em…

相關文章
相關標籤/搜索