今看到GitHub推薦了個Swift的空白頁展現庫;本着善用輪子,提升生產力的原則,下載了源碼看了下,分享給你們。git
咱們在使用App的時候,常常會出現由於請求不成功 / 數據錯誤等緣由,在應用中顯示一個空白頁,提示用戶進行操做。提示的內容包括:1.圖片, 2.標題,3.提示正文,4.操做按鈕。在這個庫,中這些提示內容都包含在EmptyStateView
裏。github
這個視圖定義了空白頁要顯示的內容以及操做。內部定義了一個ViewModel
來顯示內容。EmptyStateView
遵循NibLoadable
,NibLoadable
是讓實例對象從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)->())?
複製代碼
在使用這個庫的時候,咱們只須要設置view
的emptyState.delegate
與emptyState.dataSource
,讓代理對象遵循EmptyStateDelegate
與EmptyStateDataSource
,就能夠調用show
與Hide
方法顯示與隱藏空白頁。ide
view.emptyState.delegate = self
view.emptyState.dataSource = self
複製代碼
那麼,view
的emptyState
是怎麼出現的?做者在這裏使用了關聯對象,動態的將EmptyState
實例關聯給view
的emptyState
。ui
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)
}
}
複製代碼
操做的響應事件,經過EmptyStateView
的actionButton
,傳遞給EmptyState
的didPressActionButton()
,再傳遞到了EmptyStateDelegate
的emptyState()()()
,將事件的處理交由了代理對象處理。代理
想要空白頁顯示不一樣的圖片 / 標題 / 提示語,寫個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…