今看到GitHub推荐了个Swift的空白页展示库;本着善用轮子,提高生产力的原则,下载了源码看了下,分享给大家。
我们在使用App的时候,经常会出现因为请求不成功 / 数据错误等原因,在应用中显示一个空白页,提示用户进行操作。提示的内容包括:1.图片, 2.标题,3.提示正文,4.操作按钮。在这个库,中这些提示内容都包含在EmptyStateView里。
EmptyStateView
这个视图定义了空白页要显示的内容以及操作。内部定义了一个ViewModel来显示内容。EmptyStateView遵循NibLoadable,NibLoadable是让实例对象从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)->())?
EmptyState
在使用这个库的时候,我们只需要设置view的emptyState.delegate与emptyState.dataSource,让代理对象遵循EmptyStateDelegate与EmptyStateDataSource,就可以调用show与Hide方法显示与隐藏空白页。
view.emptyState.delegate = self
view.emptyState.dataSource = self
那么,view的emptyState是怎么出现的?作者在这里使用了关联对象,动态的将EmptyState实例关联给view的emptyState。
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里空白页都是直接设置为其背景视图。
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()()(),将事件的处理交由了代理对象处理。
定制化显示 - CustomState
想要空白页显示不同的图片 / 标题 / 提示语,写个Enum,遵循CustomState,再由对应枚举值,返回遵循CustomState,要实现的image / title / description / titileButton,返回EmptyStateFormat的实例。EmptyStateView的实例会根据format属性,更新显示内容。
//EmptyStateView的format属性,设置其值,会更新UI.
var format = EmptyStateFormat() {
didSet { updateUI() }
}
作者有个示例可以看下。
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返回对应状态下要显示的内容。
链接
EmptyStateKit:github.com/alberdev/Em…