Storybook for iOS
Storybook for iOS 是一个用于提高 UI 开发速度的库。
它使我们能够独立预览 UI 可以显示的每个组件的状态。
这个库使我们能够在大型应用中多次重建 UI 而不花费太多时间,我们可以完全构建它们而不会错过任何异常情况。
特性
- 预览任何组件的每个状态,并动态更新
- 展示任何视图控制器
- 无限创建嵌套页面
- 用有组织的排版标记组件
- 声明式语法,如 SwiftUI
基本用法
设置您的书*
使用此示例组件 MyComponent
进行展示。它只是一个填充紫色色彩的盒子。
public final class MyComponent: UIView {
public override func layoutSubviews() {
super.layoutSubviews()
backgroundColor = .systemPurple
}
public override var intrinsicContentSize: CGSize {
.init(width: 60, height: 60)
}
}
Book
表示 Storybook 的根。
Book 可以有一个描述自身的名字,我们可以在尾部闭包中声明其内容。
StorybookKit
模块。
此模块只提供描述书的符号。
import StorybookKit
let myBook = Book(title: "MyBook") {
...
}
目前我们使用 BookPreview
预览 MyComponent
。
let myBook = Book(title: "MyBook") {
BookPreview {
let myComponent = MyComponent()
return MyComponent()
}
}
要显示这本书,在任何视图控制器上显示 StorybookViewController。
StorybookUI
模块。
此模块提供显示书的特征。
import StorybookUI
let controller = StorybookViewController(book: myBook) {
$0.dismiss(animated: true, completion: nil)
}
present(controller, animated: true, completion: nil)
添加组件名称
BookPreview
可以有如下的名称标签。
BookPreview {
let component = MyComponent()
return component
}
.title("MyComponent")
列出组件的状态
一个 UI 组件可能会有多种状态,取决于某些因素。我们可以用以下方式列出该组件的每个状态。
let myBook = Book(title: "MyBook") {
BookPreview {
let button = UISwitch()
button.isOn = true
return button
}
.title("UISwitch on")
BookPreview {
let button = UISwitch()
button.isOn = false
return button
}
.title("UISwitch off")
}
当然,您可以与这些组件交互。
动态更新组件的状态
UI组件应具备根据新的状态正确更新自己的责任。
例如,根据内容自动调整大小。
为了检查这种行为,BookPreview
组件可以有一个更新组件中某些内容的按钮。
BookPreview<UILabel> {
let label = UILabel()
label.text = "Initial Value"
return label
}
.addButton("short text") { (label) in
label.text = "Hello"
}
.addButton("long text") { (label) in
label.text = "Hello, Hello,"
}
展示ViewController
当需要检查弹出窗口时,我们使用BookPresent
声明。
BookPresent(title: "Pop") {
let alert = UIAlertController(
title: "Hi Storybook",
message: "As like this, you can present any view controller to check the behavior.",
preferredStyle: .alert
)
alert.addAction(.init(title: "Got it", style: .default, handler: { _ in }))
return alert
}
BookPresent(title: "Another Pop") {
let alert = UIAlertController(
title: "Hi Storybook",
message: "As like this, you can present any view controller to check the behavior.",
preferredStyle: .alert
)
alert.addAction(.init(title: "Got it", style: .default, handler: { _ in }))
return alert
}
高级用法
为组织而创建指向其他页面的链接
增加组件数量,页面将会有很长的垂直滚动。
在这种情况下,Storybook为你提供了使用BookNavigationLink
创建另一个页面的功能。
let myBook = Book(title: "MyBook") {
BookNavigationLink(title: "UISwitch") {
BookPreview {
let button = UISwitch()
button.isOn = true
return button
}
.title("UISwitch on")
BookPreview {
let button = UISwitch()
button.isOn = false
return button
}
.title("UISwitch off")
}
}
标记
我们可以添加一些描述和标题来阐明组件的实现。
let myBook = Book(title: "MyBook") {
BookNavigationLink(title: "UISwitch") {
BookPage(title: "UISwitch variations") {
BookHeadline("This page previews UISwitch's state.")
BookParagraph("""
Mainly, UISwitch has 2 states that are `on` or `off`.
This page shows you how it presents appearances in each state.
""")
BookPreview {
let button = UISwitch()
button.isOn = true
return button
}
.title("UISwitch on")
BookPreview {
let button = UISwitch()
button.isOn = false
return button
}
.title("UISwitch off")
}
}
}
您可以使用以下声明进行标记。
BookPage
BookSection
BookParagraph
BookHeadline
BookText
分离声明
随着组件数量和描述的增多,Book的声明代码也越来越长。
在这种情况下,我们可以通过几个函数来分离代码。
let myBook = Book(title: "MyBook") {
uiswitchPage()
}
func uiswitchPage() -> BookView {
BookNavigationLink(title: "UISwitch") {
BookPreview {
let button = UISwitch()
button.isOn = true
return button
}
.title("UISwitch on")
BookPreview {
let button = UISwitch()
button.isOn = false
return button
}
.title("UISwitch off")
}
}
构建UI组件模式
为了检查UI组件的外观变化,这取决于输入参数,我们可以使用BookForEach
和BookPattern
生成这些模式。
BookForEach(data: BookPattern.make(
["A", "AAA", "AAAAAA"],
[UIColor.blue, UIColor.red, UIColor.orange]
)) { (args) in
BookPreview {
let (text, color) = args
let label = UILabel()
label.text = text
label.textColor = color
return label
}
}
快速开发UI的项目结构
特别是在基于UIKit的应用中,检查UI变化需要很多次构建。
减少这种时间的最佳方法是为仅包含应用程序中使用到的UI组件创建单独的模块。
并为仅运行Storybook创建新的应用目标。
最后,将主应用和Storybook应用链接到该分离的模块。
当您正在调整它们时,您可以仅通过Storybook应用进行构建。
- UIComponent(动态或静态库/框架)
- MainApp(可执行文件)
- StorybookApp(可执行文件)
要求
- iOS 10.0+
- Xcode 11.4+
- Swift 5.2+
安装
CocoaPods
CocoaPods 是一个用于 Cocoa 项目的依赖管理器。有关使用和安装说明,请访问他们的网站。要使用 CocoaPods 将 Alamofire 集成到您的 Xcode 项目中,请在 Podfile 中指定它。
pod 'StorybookKit'
pod 'StorybookUI'
授权协议
Storybook-ios 在 MIT 许可协议下发布。