Bindy 0.3.3

Bindy 0.3.3

Maxim Kotliar 维护。



Bindy 0.3.3

  • Maxim Kotliar

Awesome Build status Version License Platform

Bindy

只是一个简单的绑定。

安装

请将pod 'Bindy'

添加到你的podfile中,并运行pod install

SPM也受支持。

用法

目前,Bindy有几个基本类型

  • Signal - 允许在接收到某些信号时触发回调。
  • Observable - 允许观察值的改变。
  • ObservableArray - 遵循MutableCollection协议,因此你可以像处理普通数组一样处理它:索引、替换对象、映射、枚举等... 此外,ObservableArray还有一个updates信号,它将通知你数组中发生的任何更改,如插入、替换、删除。

Observables 示例(使用属性包装器更新)

@Observable var firstname = "Salvador"
@Observable var age = 54

func setupBindings() {
    $age.bind(self) { [unowned self] newAge in
            print("Happy \(newAge) birthday, \(firstname)")
    }
    age = 55
}

请始终在闭包中使用 [unowned owner] 以防止保留周期。

信号和数组样例

let messages: ObservableArray<Message> = []
let newMessage = Signal<Message>()
    
func setupBindings() {
    newMessage.bind(self) { [unowned self] message in
            self.messages.append(message)
    }
    
    messages.updates.bind(self) { [unowned tableView] updates in
            self.tableView.pefrom(updates: updates)     
       }
}
       
func handleDidRecieveMessage(_ message: Message) {
     newMessage.send(message)      
    }
}

如果不希望手动解除绑定,则无需手动移除。当你在bind(_ owner: AnyObject...方法中作为所有者传递的对象释放时,相应的绑定将自动解绑。然而,如果您想手动解绑,只需调用unbind(_ owner: AnyObject)。Bindy为tableView扩展了一个用于执行更新的函数tableView.perform(updates:...

此外,观察者对象有一个observe(_ owner: AnyObject...方法,它类似于bind,但会立即触发回调,这在某些情况下可能更方便。

转换

如果您想要接收已转换类型的事件,您可以在Observables上使用transform函数,如下:

let speed = Observable(20)
lazy var speedString = speed.transform { "\($0)km/h" }
    
func setupBindings() {
    speedString.observe(self) { [unowned self] speedString in
        // speedString = "20km/h"
            self.speedLabel.text = speedString
        }
}

组合

您可以使用combined(with: ..., transform: ...)函数将两个Observables类型组合起来。

let firstname = Observable("Maxim")
let lastname = Observable("Kotliar")
let age = Observable(24)

lazy var fullName = firstname
            .combined(with: lastname) { "name: \($0) \($1)" }
            .combined(with: age) { "\($0), age: \($1)" }

func setupBindings() {
    userInfo.observe(self) { [unowned self] info in
            // info = "name: Maxim Kotliar, age:24"
            self.userInfoLabel.text = info
        }
}

对于Observable<Bool>的组合,Bindy提供了更方便的操作符&&||,所以您可以像常规Bool一样组合Observable<Bool>,也可以使用!进行反转。

let isPremiumPurchased = Observable(true)
let isInTrialPeriodEnded = Observable(false)
let isAdsShowForced = Observable(false)

lazy var shouldShowAds = isAdsShowForced || !isPremiumPurchased && isInTrialPeriodEnded

KVO支持

Bindy支持KVO,因此您可以使用简单的下标语法从任何KVO支持的属性创建Observable,如:

let textField = UITextField()
let text = textField[\.text] // type will be Observable<String?>

text.observe(self) { newText in
    print(newText)
}

旧值

对于任何Observable类型,你可以在闭包中接收到旧值,只需向绑定闭包传递两个参数,第一个参数将是旧值,第二个参数为新值。

let observableString = Observable("test")

observableString.bind(self) { oldString, newString in
    print("String changed from \(oldString) to \(newString)")
}

高阶函数

Bindy 包含一些高阶函数

  • map - 在任何类型上应用,行为类似于 Swift 的 map。
  • flatMap - 在可选类型的 Observable 上应用,返回非可选类型的 Signal。
  • compactMap - 在包含集合的 Observable 上应用,行为类似于 Swift 函数。
  • reduce - 在包含集合的 Observable 上应用,行为类似于 Swift 函数。
  • filter - 在包含集合的 Observable 上应用,行为类似于 Swift 函数。