项目 Fisticuffs
Fisticuffs 是一个受 Knockout 启发的 Swift 数据绑定框架,共享了许多相同的概念。
-
声明式绑定
通过在单个地方设置所有视图逻辑来简化您的视图控制器。无需实现目标-动作、代理方法等。
-
自动更新
您的数据更改时,您的 UI 会自动更新以反映这些更改。同样,当用户与您的 UI 交互时,您的数据会自动更新。
-
自动依赖跟踪
轻松且隐式地设置依赖图。当底层依赖项的值更改时,Fisticuffs 会确保这些更改被传播。
快速示例
因为一个代码片段可以胜过千言万语...
class LoginViewController: UIViewController {
@IBOutlet var usernameField: UITextField!
@IBOutlet var passwordField: UITextField!
@IBOutlet var loginButton: UIButton!
let username = Observable("")
let password = Observable("")
lazy var inputIsValid: Computed<Bool> = Computed { [weak self] in
let user = self?.username.value
let pass = self?.password.value
return user?.isEmpty == false && pass?.isEmpty == false
}
override viewDidLoad() {
super.viewDidLoad()
// bind the text in our username & password fields to their
usernameField.b_text.bind(username)
passwordField.b_text.bind(password)
// only enable the login button if they've entered an username and password
loginButton.b_enabled.bind(inputIsValid)
// do the login when the user taps the login button
loginButton.b_onTap.subscribe { [weak self] in
LoginManager.doLogin(self?.username.value, self?.password.value)
}
}
}
核心概念
可观察对象
可观察对象
类是 Fisticuffs 的基本构建模块之一。它存储一个值,当该值变化时,会通知所有订阅者。
let observable = Observable<String>("")
observable.subscribe { oldValue, newValue in
print(newValue)
}
observable.value = "Hello, world"
// prints "Hello, world"
计算值
计算值
是 可观察对象
的只读同级。它使用闭包来计算其值。此外,当任何其 可观察对象
(和 计算值
)依赖项变化时,它会自动更新其值。例如
let name = Observable<String>("")
let greeting: Computed<String> = Computed {
return "Hello, " + name.value
}
greeting.subscribe { oldValue, newValue in
print(newValue)
}
name.value = "world"
// prints "Hello, world" because the change to `name` is propagated up to `greeting`
事件
最后,事件
类提供了向其订阅者广播事件的机制。它和 可观察对象
计算值
有相似的接口。
let event = Event<String>()
event.subscribe { _, str in
print(str)
}
event.fire("Hello, world")
// prints "Hello, world"
可订阅对象
顺便提一下,可观察对象
、计算值
和 事件
都继承自 可订阅对象
,以提供一个通用的接口来订阅变化/事件。
绑定处理程序
绑定处理程序
描述了如何将原始数据值(例如 Int
、String
、NSDate
等..)应用于属性(如 UILabel.text
、UIImageView.image
等..)
一些使用绑定处理程序可以完成的实用示例
BindingHandlers.loadImage()
- 允许将NSURL
绑定到UIImage
属性BindingHandlers.formatSalary()
- 将原始薪资Int
格式化为漂亮的字符串(例如100k
)BindingHandlers.autoupdatingTimeAgo()
- 启用将NSDate
绑定到String
属性(例如:UILabel.text
)的功能,以显示类似“5分钟前”等值(并且会随着时间的推移自动更新显示的字符串)
通常,原始值(例如:Double
格式的虚拟积分)应该在视图模型中向上冒泡到 UI,以便根据该视图的需要进行格式化。
UI 绑定
属性绑定
许多 UIKit
类被扩展以允许将它们的属性绑定到 Subscribables
。这些属性通常是:
UIKit | 拳法 |
---|---|
UILabel .text |
UILabel .b_text |
UITextField .text |
UITextField .b_text |
UIButton .enabled |
UIButton .b_enabled |
UISwitch .on |
UISwitch .b_on |
等等... |
要将 Subscribable
(例如:Observable
、Computed
等)绑定到这些属性,可以使用 bind()
方法。
let messageLabel: UILabel = ...
let message = Observable("")
messageLabel.b_text.bind(message)
事件
UI 事件作为 Event
之外的,使得将行为附加到控件变得简单。例如
let button: UIButton = ...
button.b_onTap.subscribe {
print("Pressed button!")
}
UITableViews / UICollectionViews
拳法提供了将数据轻松绑定到 UITableViews / UICollectionViews 的支持。下面是示例:
let tableView: UITableView = ...
let days = Observable(["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"])
tableView.registerClass(UITableViewCell.self forCellReuseIdentifier: "Cell")
tableView.b_configure(days) { config in
config.useCell(reuseIdentifier: "Cell") { day, cell in
cell.textLabel?.text = day
}
config.allowsMoving = true // let user reorder the days
config.allowsDeletion = true // let user delete days (good-bye Monday! :)
}
需要注意的是一些有趣的事情
- 由于设置了
allowsMoving
和allowsDeletion
,用户可以移动和删除行。底层数据(days
)将自动更新 - 对
days
的任何代码更新都将传播到表格视图(包括动画插入、删除等)
对于 UICollectionView
也存在类似的绑定
安装
要求
- Xcode 10 / Swift 4.2
- iOS 8+
CocoaPods
-
如果还没有安装,请安装CocoaPods并为使用CocoaPods设置您的项目。
-
将
Fisticuffs
添加到您的Podfile
。
pod 'Fisticuffs', '0.0.8'
- 运行
pod install
注意:在1.0版本之前可能会有破坏性更改,建议锁定到特定版本。
Carthage
-
如果已经安装,请安装Carthage并为使用它设置您的项目。请参见这里。
-
将
Fisticuffs
添加到您的Cartfile
。
github "scoremedia/Fisticuffs" == 0.0.8
- 运行
carthage update
在1.0版本之前可能会有破坏性更改,建议锁定到特定版本。
手动安装
-
下载此存储库(如果使用Git,您可以将它添加为子模块)
-
将
Fisticuffs.xcodeproj
拖放到您的Xcode项目或工作区中 -
将
Fisticuffs.framework
添加到您的应用中的《嵌入二进制文件》和《链接的框架和库》
示例/测试
测试和一些示例在Fisticuffs.xcworkspace
中提供。
运行测试
git submodule update --init --recursive
-
打开
Fisticuffs.xcworkspace
,选择Fisticuffs
构建方案 -
产品 → 测试
许可证
Fisticuffs 采用 MIT 许可协议发布。