StatefulViewController
一个协议,允许 UIViewController
或 UIView
基于内容、加载、错误或空状态显示占位视图。
概述
在网络应用程序中,视图控制器或自定义视图通常有以下需要通知用户的状态
- 加载:内容正在通过网络加载。
- 内容:内容可用并呈现给用户。
- 空:当前没有可显示的内容。
- 错误:在下载数据时发生错误。
尽管这个流程听起来很简单,但实际上有很多情况会导致一个相当大的决策树。
StatefulViewController
是这个特定决策树的具体实现。(如果您想创建自己的修改版本,您可能对用于显示和隐藏视图的状态机感兴趣。)
版本兼容性
当前 Swift 兼容性分析
Swift 版本 | 框架版本 |
---|---|
4.2 | 1.1.x |
4.0 | 1.0.x |
3.0 | 3.x |
2.3 | 2.x |
2.2 | 1.x |
使用说明
本指南描述了在
UIViewController
上使用StatefulViewController
协议。但是,您也可以在任何UIViewController
子类上采用StatefulViewController
协议,例如UITableViewController
或UICollectionViewController
,以及您自定义的UIView
子类。
首先,确保您的视图控制器采用了 StatefulViewController
协议。
class MyViewController: UIViewController, StatefulViewController {
// ...
}
然后,在 viewDidLoad
中配置 loadingView
、emptyView
和 errorView
属性(由 StatefulViewController
协议提供)。
override func viewDidLoad() {
super.viewDidLoad()
// Setup placeholder views
loadingView = // UIView
emptyView = // UIView
errorView = // UIView
}
此外,在 viewWillAppear:
中调用 setupInitialViewState()
方法,以确保设置控制器的初始状态。
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
setupInitialViewState()
}
之后,只需通知视图控制器内容何时正在加载,StatefulViewController
将代表您显示和隐藏正确的加载、错误和空视图。
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
loadDeliciousWines()
}
func loadDeliciousWines() {
startLoading()
let url = NSURL(string: "http://example.com/api")
let session = NSURLSession.sharedSession()
session.dataTaskWithURL(url) { (let data, let response, let error) in
endLoading(error: error)
}.resume()
}
生命周期
StatefulViewController
会调用 hasContent
方法来检查是否有内容需要显示。如果您在自己的类中没有重写此方法,StatefulViewController
将始终假设有内容需要显示。
func hasContent() -> Bool {
return datasourceArray.count > 0
}
可选地,即使内容已经显示,您可能仍然想要响应错误。在这种情况下,StatefulViewController
不会显示其 errorView
,因为有可以显示的内容。
例如,要显示自定义警报或其他不会被注意到的错误消息,请使用 handleErrorWhenContentAvailable:
手动向用户呈现错误。
func handleErrorWhenContentAvailable(error: ErrorType) {
let alertController = UIAlertController(title: "Ooops", message: "Something went wrong.", preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(alertController, animated: true, completion: nil)
}
自定义占位符视图边距
默认情况下,StatefulViewController 以全屏方式(即从父视图的顶部、底部、左侧和右侧均无内边距)显示所有配置的占位符视图。如果一个占位符视图需要自定义内边距,可以配置的占位符视图可能遵守 StatefulPlaceholderView
协议并覆盖 placeholderViewInsets
方法以返回自定义的边缘内边距。
class MyPlaceholderView: UIView, StatefulPlaceholderView {
func placeholderViewInsets() -> UIEdgeInsets {
return UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
}
}
视图状态机
注意:以下部分仅面向那些想要创建与上述流程不同的状态控制器的用户。
您还可以使用底层视图状态机为您的自定义显示/隐藏视图流程创建类似的实现。
let stateMachine = ViewStateMachine(view: view)
// Add states
stateMachine["loading"] = loadingView
stateMachine["other"] = otherView
// Transition to state
stateMachine.transitionToState(.View("loading"), animated: true) {
println("finished switching to loading view")
}
// Hide all views
stateMachine.transitionToState(.None, animated: true) {
println("all views hidden now")
}
安装
使用 Carthage
将以下行添加到您的 Cartfile 中。
github "aschuch/StatefulViewController" ~> 3.0
然后运行 carthage update
。
使用 CocoaPods
将以下行添加到您的 Podfile。
pod "StatefulViewController", "~> 3.0"
然后使用 CocoaPods 0.36 或更高版本运行 pod install
。
手动操作
只需将 StatefulViewController
文件夹中的两个 .swift
文件拖放到您的项目中即可。
测试
打开 Xcode 项目,按 ⌘-U
运行测试。
或者,您可以使用 xctool 从终端运行所有测试。
xctool -scheme StatefulViewControllerTests -sdk iphonesimulator test
待办事项
- 默认加载、错误、空视图
- 协议在视图中通知它们关于移除和添加的操作
- 视图可以提供延迟,以便告诉状态机在特定延迟之后显示/移除它们(例如,用于隐藏和显示动画)
贡献
- 创造一些精彩的东西,让代码更优,添加一些功能,等等(这是最难的部分)。
- Fork它
- 创建新分支以进行更改
- 提交您分支下的所有更改
- 提交pull request
联系我们
随时欢迎与我们联系。