StatefulUI 1.0.5

StatefulUI 1.0.5

David Jennes 维护。



 
依赖
IBAnimatable>= 0
Reusable>= 0
 

  • 英文
  • David Jennes

StatefulUI

Swift 5.0 Platform

一个协议,允许 UIViewControllerUIView 根据内容、加载、错误或空状态呈现占位符视图。

StatefulViewController Example

概览

在联网应用程序中,视图控制器或自定义视图通常有以下需要通知用户的状态

  • 加载: 内容正在通过网络加载。
  • 内容: 内容可用并展示给用户。
  • 空: 当前没有可展示的内容。
  • 错误: 下载内容时发生错误。

尽管这个流程听起来可能很简单,但有很多情况会导致一个相当大的决策树。

Decision Tree

StatefulViewController 是这个特定决策树的具体实现。(如果想要创建自己的修改版,可能会对用于显示和隐藏视图的状态机感兴趣。)

使用方法

本指南描述了 StatefulViewController 协议在 UIViewController 上的使用。但您也可以在 UIViewController 的任何子类(如 UITableViewControllerUICollectionViewController)以及您的自定义 UIView 子类上采用 StatefulViewController 协议。

首先,确保您的视图控制器采用 StatefulViewController 协议。

class MyViewController: UIViewController, StatefulViewController {
    // ...
}

然后,在 viewDidLoad 中配置 loadingViewemptyViewerrorView 属性(由 StatefulViewController 协议提供)。您可以使用提供的默认视图,这些视图可以通过多种方式配置(请注意,其中一些接受 delegate 以处理按钮点击的回调)。

override func initializeEmptyStateViews() {
    emptyView = StateEmptyView.load(subtitle: "No items found", delegate: self)
    errorView = StateErrorView.load(delegate: self)
    loadingView = StateLoadingView.load()
}

之后,只需告诉视图控制器何时内容正在加载,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) { [weak self] (let data, let response, let error) in
        self?.endLoading(error: error)
    }.resume()
}

生命周期

StatefulViewController 调用 hasContent 方法以检查是否存在任何可显示的内容。如果您在自己的类中没有重写此方法,则 StatefulViewController 将始终假定有内容要显示。已经为 UITableViewUICollectionView 及其控制器变体提供了默认实现。

func hasContent() -> Bool {
    return datasourceArray.count > 0
}

可选地,即使在内容已经显示的情况下,您可能也想对错误做出响应。在这种情况下,StatefulViewController 不会显示其 errorView,因为已经有内容可以显示。

例如,要显示自定义弹窗或其他不干扰的错误消息,请使用 handleErrorWhenContentAvailable: 手动将错误显示给用户。

func handleErrorWhenContentAvailable(error: ErrorType) {
    let alert = UIAlertController(title: "Ooops", message: "Something went wrong.", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
    presentViewController(alert, animated: true)
}

类似地,即使已显示内容,您也可能想要向用户显示活动。实现 subtleActivityIndicatorView 属性并提供活动指示器

var subtleActivityIndicatorView: ActivityIndicatingView? {
    return footerActivityIndicator
}

自定义占位视图的内边距

默认情况下,StatefulViewController 以全屏方式(即从父视图顶部、底部、左侧和右侧的0内边距)显示所有配置的占位视图。如果占位视图应具有自定义内边距,则配置的占位视图可以遵守 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")
}

安装

CocoaPods

在您的Podfile中添加以下行。

pod "StatefulUI", "~> 1.0"

然后使用CocoaPods 1.4或更高版本运行pod install

贡献

  • 创建出一些精彩的东西,优化代码,添加一些功能,等等(这部分是最难的)。
  • Fork它
  • 创建新分支以进行更改
  • 将所有更改提交到您的分支
  • 提交pull request

鸣谢

StatefulUI 是由 David Jennes 提供的,它基于 StatefulViewController 的分支,最初由 @schuchalexander 编写。

授权协议

StatefulUI 在MIT授权协议下可用。有关更多信息,请参阅LICENSE文件。