Cyanic
Cyanic 是一个只为 iOS 平台开发的框架,由 Feil, Feil, & Feil GmbH 根据对状态驱动 UI 的需求创建。它大量借鉴了 Airbnb 的 MvRx 框架(我们的 Android 开发者正在使用这个框架)来创建一个与 Android 非常相似的代码库,从而统一了两个平台上的业务逻辑。我们使用这个框架来创建复杂、响应快且高性能的屏幕。
Cyanic 是一个完全使用 Swift 编写的框架。没有计划支持 Objective-C。
安装
CocoaPods
要求
- Swift 5.0+
- iOS 10.0+
-
将以下内容添加到您的 Podfile
pod 'Cyanic' pod 'LayoutKit', :git => 'https://github.com/hooliooo/LayoutKit.git' // Use this fork until LayoutKit is updated
-
使用框架集成依赖项:在 Podfile 中添加
use_frameworks!
。 -
运行
pod install
。
为什么使用 LayoutKit 的分叉版本
LayoutKit 是负责 Cyanic 中大部分 UI 逻辑的库。然而,截至 2019 年 4 月 17 日,当前 LayoutKit 版本在 Cocoapods 中存在一些限制。
- 它并未更新以使用 Swift 5。
- Cyanic 需要访问允许您将 UIView 子类类型作为参数声明的 Layouts 内部初始化器。
如果不进行这些更改,Cyanic 将继续使用分支版本。
文档
请查看我们维基以获取完整文档。
简单示例
一个非常简单的带有可展开功能的示例
struct YourState: ExpandableState {
enum Section: String, CaseIterable {
case first
case second
}
static var `default`: YourState {
return YourState(
text: "Hello, World!",
expandableDict: YourState.Section.allCases.map { $0.rawValue }
.reduce(into: [String: Bool](), { (current: inout [String: Bool], id: String) -> Void in
current[id] = false
}
)
}
var text: String
var expandableDict: [String: Bool]
}
class YourViewModel: ViewModel<YourState> {
func showCyanic() {
self.setState { $0.text = "Hello, Cyanic!" }
}
}
class YourComponentViewController: SingleSectionCollectionComponentViewController {
private let viewModel: YourViewModel = YourViewModel(initialState: YourState.default)
override var viewModels: [AnyViewModel] {
return [self.viewModel.asAnyViewModel]
}
override func buildComponents(_ componentsController: inout ComponentsController) {
withState(self.viewModel) { (state: YourState) -> Void in
componentsController.staticTextComponent {
$0.id = "title"
$0.text = state.text
}
componentsController.buttonComponent {
$0.id = "button"
$0.onTap = { [weak self]
self?.viewModel.showCyanic()
}
}
let firstExpandableID: String = YourState.Section.first.rawValue
let yourExpandable = components.expandableComponent { [weak self] in
guard let s = self else { return }
$0.id = firstExpandableID
$0.contentLayout = LabelContentLayout(text: Text.unattributed("Hello, World!"))
$0.isExpanded = state.expandableDict[firstExpandableID] ?? false
$0.setExpandableState = self.viewModel.setExpandableState
$0.backgroundColor = UIColor.lightGray
$0.height = 55.0
}
// These ButtonComponents will only show up when yourExpandable is expanded.
if yourExpandable.isExpanded {
for number in 1...5 {
componentsController.buttonComponent {
$0.id = "button\(number)"
$0.title = "\(number)"
$0.onTap = { [weak self]
print("Hello, World from Button \(number)")
}
}
}
}
}
}
}
贡献者
- Julio Alorro ([email protected])
- Jonas Bark ([email protected])
- Alexander Korus ([email protected])