Fisticuffs 0.1.2

Fisticuffs 0.1.2

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2024年3月
SPM支持 SPM

Darren ClarkMahmood TahirEugene Kwong 维护。



  • Darren Clark

项目 Fisticuffs

Fisticuffs 是一个受 Knockout 启发的 Swift 数据绑定框架,共享了许多相同的概念。

  • 声明式绑定

    通过在单个地方设置所有视图逻辑来简化您的视图控制器。无需实现目标-动作、代理方法等。

  • 自动更新

    您的数据更改时,您的 UI 会自动更新以反映这些更改。同样,当用户与您的 UI 交互时,您的数据会自动更新。

  • 自动依赖跟踪

    轻松且隐式地设置依赖图。当底层依赖项的值更改时,Fisticuffs 会确保这些更改被传播。


⚠️ 注意: Fisticuffs 仍然是 alpha/beta。希望公共接口不会改变太多,但在 1.0 版本之前不能保证。

快速示例

因为一个代码片段可以胜过千言万语...

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"

可订阅对象

顺便提一下,可观察对象计算值事件 都继承自 可订阅对象,以提供一个通用的接口来订阅变化/事件。

绑定处理程序

绑定处理程序 描述了如何将原始数据值(例如 IntStringNSDate 等..)应用于属性(如 UILabel.textUIImageView.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(例如:ObservableComputed 等)绑定到这些属性,可以使用 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! :)
}

需要注意的是一些有趣的事情

  • 由于设置了 allowsMovingallowsDeletion,用户可以移动和删除行。底层数据(days)将自动更新
  • days 的任何代码更新都将传播到表格视图(包括动画插入、删除等)

对于 UICollectionView 也存在类似的绑定

安装

要求

  • Xcode 10 / Swift 4.2
  • iOS 8+

CocoaPods

  1. 如果还没有安装,请安装CocoaPods并为使用CocoaPods设置您的项目。

  2. Fisticuffs添加到您的Podfile

pod 'Fisticuffs', '0.0.8'
  1. 运行pod install

注意:在1.0版本之前可能会有破坏性更改,建议锁定到特定版本。

Carthage

  1. 如果已经安装,请安装Carthage并为使用它设置您的项目。请参见这里

  2. Fisticuffs添加到您的Cartfile

github "scoremedia/Fisticuffs" == 0.0.8
  1. 运行carthage update

在1.0版本之前可能会有破坏性更改,建议锁定到特定版本。

手动安装

  1. 下载此存储库(如果使用Git,您可以将它添加为子模块

  2. Fisticuffs.xcodeproj拖放到您的Xcode项目或工作区中

  3. Fisticuffs.framework添加到您的应用中的《嵌入二进制文件》和《链接的框架和库》

示例/测试

测试和一些示例在Fisticuffs.xcworkspace中提供。

运行测试

  1. 克隆此仓库

  2. 要获取 QuickNimble,运行

git submodule update --init --recursive
  1. 打开 Fisticuffs.xcworkspace,选择 Fisticuffs 构建方案

  2. 产品测试

许可证

Fisticuffs 采用 MIT 许可协议发布。