KPDataBinding 0.0.7

KPDataBinding 0.0.7

tonnylitao 维护。



  • Tonny

KPDataBinding

一个具有 Swift KeyPath 的数据绑定库

安装

pod 'KPDataBinding'

特性

  • 不仅在模型中,而且在视图中利用 KeyPath
  • 单向和双向数据绑定
  • 多个视图绑定到同一个模型的属性
  • 数据格式和转换
  • 中缀运算符
  • 解除绑定

单向数据绑定

struct User {
    var aString:        String?
    var aButtonTitle:   String?
}

let userViewModel = KPDataBindingViewModel<User>()

userViewModel.bind(User(), [
    uiLabel     <-  \User.aString,
    uiButton    <-  \User.aButtonTitle,
])

userViewModel.update(\.aString, with: "A new text")

//userViewModel.model.aString == "A new text"
//uiLabel.text == "A new text"


userViewModel.update(\.aButtonTitle, with: "A new text")

//userViewModel.model.aButtonTitle == "A new text"
//uiButton.title(for: .normal) == "A new text"
单向数据绑定中的类型转换
  • 格式化数据以在视图中显示
struct User {
    var aInt: Int
}

userViewModel.bind(User(), [
    uiLabel <~ (\User.aInt, toLabel: { $0.text = "Your Age: \($0)" }),
])

userViewModel.update(\.aInt, with: 1)

//userViewModel.model.aInt == 1
//uiLabel.text == "Your Age: 1"

双向数据绑定

struct User {
    var aString:    String?
    var isOn:       Bool
    var isSelected: Bool
    var isSelected: Bool
    var aFloat:     Float
    var aDouble:    Double
}

userViewModel.bind(initialData, [
    uiTextField     <-> \User.aString,
    uiSwitcher      <-> \User.isOn,
    uiButton        <-> \User.isSelected,
    uiSlider        <-> \User.aFloat,
    uiSteper        <-> \User.aDouble,
])

//view value and model value will be equal 

//userViewModel.model.isOn == uiSwitcher.isOn

//userViewModel.model.isSelected == uiButton.isSelected

//userViewModel.model.aFloat == uiSlider.value

//userViewModel.model.aDouble == uiSteper.value

注意:UITextField的默认文本为@""。https://developer.apple.com/documentation/uikit/uitextfield/1619635-text

userViewModel.update(\.aString, with: nil)
//userViewModel.model.aString == nil
//uiTextField.text == ""

userViewModel.update(\.aString, with: "A new String")
//userViewModel.model.aString == "A new String"
//uiTextField.text == "A new String"
双向数据绑定中的格式化和类型转换
  • 格式化数据以在视图中显示
  • 类型转换视图值到模型
userViewModel.bind(initialData, [
    ageSteper <~> (\User.age, { $0.value = Double($1) }, { view, _ in Int(view.value) }),
])

userViewModel.update(\.aInt, with: 1)

//userViewModel.model.aInt == 1
//uiSteper.value == Double(1)


//uiSteper's value changed to 3.0
//userViewModel.model.aInt == Int(3.0)

更新模型和视图

始终通过ViewModel更新模型,绑定视图将自动更新。

userViewModel.update(\User.name, with: "A new Name")

解绑

userViewModel.unbind(\User.name)

使用KPDataBinding在实际操作中的数据绑定

import KPDataBinding

class ViewController: UIViewController {
    
    @IBOutlet weak var groupNameLbl:     UILabel!
    @IBOutlet weak var nameField:        UITextField!
    @IBOutlet weak var emailField:       UITextField!
    @IBOutlet weak var ageLbl:           UILabel!
    @IBOutlet weak var ageSteper:        UIStepper!
    @IBOutlet weak var activitySlider:   UISlider!
    @IBOutlet weak var likeKiwiSwitcher: UISwitch!
    @IBOutlet weak var travelBtn:        UIButton!
    @IBOutlet weak var hikingBtn:        UIButton!
    @IBOutlet weak var readingBtn:       UIButton!
    
    lazy var userViewModel = KPDataBindingViewModel<User>()
    
    
    override func viewDidLoad() {
        
        let initialData = User(groupName: "Save NZ Animals Group 1", name: "Tonny")
        
        userViewModel.bind(initialData, [
            groupNameLbl     <-  \User.groupName,
            travelBtn        <-  \User.name,
            
            nameField        <-> \User.name,
            emailField       <-> \User.email,
            activitySlider   <-> \User.activity,
            likeKiwiSwitcher <-> \User.likeKiwi,
            travelBtn        <-> \User.travel,
            hikingBtn        <-> \User.hiking,
            readingBtn       <-> \User.reading,

            ageLbl           <~  (\User.age, { $0.text = "Your Age: \($1)" }),
            
            ageSteper        <~> (\User.age, { $0.value = Double($1) }, { view, _ in Int(view.value) }),
        ])
    }
    
    @IBAction func submit(_ sender: Any) {
        let data = userViewModel.model
        
        ...
    }
}

KPDataBinding如何与KeyPath结合使用?

model[keyPath: \User.name] = "Tonny"       //update model
view[keyPath: \UITextField.text] = "Tonny" //update view


view[keyPath: \UITextField.text] = model[keyPath: \User.name]  //update view from model


view.addTarget(self, #selector(viewChanged), for: event)

func viewChanged(view: UITextField) {
    model[keyPath: \User.name] = view[keyPath: \UITextField.text]  //update model from view
}

许可证

KPDataBinding 在 MIT 许可协议下可用。有关更多信息,请参阅 LICENSE 文件。