SwiftBondを試してみました。
インストール
CocoaPodsでインストールします。
podには"SwiftBond"でなく"Bond"と入れます。
platform :ios, "8.0" use_frameworks! pod "Bond"
ViewとModelを繋いでみます
ViewController, Storyboard, ViewModelを用意します。
Storyboardには下のようにLabelとTextFieldを貼り付けます。
次にViewModelを作ります。
import Foundation import Bond class ViewModel { var text = Observable<String?>("初期値") }
最後にViewControllerを作り、その中でLabelとTextFieldをViewModelに紐付けます。
import UIKit class ViewController: UIViewController { @IBOutlet weak var label: UILabel! @IBOutlet weak var textField: UITextField! let viewModel = ViewModel() override func viewDidLoad() { textField.bnd_text.bindTo(viewModel.text) // textFieldの値が変わったらviewModel.textに反映される label.bnd_text.bidirectionalBindTo(viewModel.text) // 双方向バインディング、viewModel.textの値が変わった場合にもViewに反映される } }
実際に動かすと、TextFieldの値を変更したらLabelにも反映されるようになりました。
お手軽にTextFieldとLabelを紐付ける
TextFieldとLabelをつなげるだけなら下の書き方でもいけるようです。
// textField.bnd_text.bindTo(viewModel.text) // textFieldの値が変わったらviewModel.textに反映される // label.bnd_text.bidirectionalBindTo(viewModel.text) textField.bnd_text ->> label.bnd_text
Labelに値を渡す時に加工する
mapを使えば渡す文字列を加工する事ができます
textField.bnd_text.map { $0! + "!" } ->> label.bnd_text // LabelにはTextFieldの値に!を付けた文字が入る
特定条件の時だけLabelに反映する
filterを
textField.bnd_text.filter { $0?.characters.count < 3 } ->> label.bnd_text // 3文字以上の場合はLabelに値が反映されない
TextFieldの値の変更時イベントを取得する
イベントの取得だけならobserve
でできるようです。
textField.bnd_text.observe { text in print(text) }
UITableView
UITableViewとDataSourceは下のように紐付けます。
class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { let array1 = ObservableArray(["1つ目", "2つ目", "3つ目"]) let array2 = ObservableArray(["First", "Second"]) let dataSource = ObservableArray([array1, array2]) dataSource.bindTo(tableView) { indexPath, dataSource, tableView in let cell = tableView.dequeueReusableCellWithIdentifier( "Cell", forIndexPath: indexPath) let name = dataSource[indexPath.section][indexPath.row] cell.textLabel?.text = name return cell } } }
UITableViewのその他のdataSource
BNDTableViewProxyDataSourceを使う事でSectionHeaderのカスタマイズもできます。
しかしBNDTableViewProxyDataSourceには
class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { let array1 = ObservableArray(["1つ目", "2つ目", "3つ目"]) let array2 = ObservableArray(["First", "Second"]) let dataSource = ObservableArray([array1, array2]) dataSource.bindTo(tableView, proxyDataSource: self) { indexPath, dataSource, tableView in let cell = tableView.dequeueReusableCellWithIdentifier( "Cell", forIndexPath: indexPath) let name = dataSource[indexPath.section][indexPath.row] cell.textLabel?.text = name return cell } } } extension ViewController: BNDTableViewProxyDataSource { func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return "Header" } }
didSelect等のdelegateメソッド
delegateメソッドは普通にselfを指定するようです。
class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { let array1 = ObservableArray(["1つ目", "2つ目", "3つ目"]) let array2 = ObservableArray(["First", "Second"]) let dataSource = ObservableArray([array1, array2]) dataSource.bindTo(tableView) { indexPath, dataSource, tableView in let cell = tableView.dequeueReusableCellWithIdentifier( "Cell", forIndexPath: indexPath) let name = dataSource[indexPath.section][indexPath.row] cell.textLabel?.text = name return cell } tableView.delegate = self } } extension ViewController: UITableViewDelegate { func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { print("SELECT!!!") } }
参考URL
Swift bondでつなげてプログラミング - Software
SwiftBondでデータバインドを実現する - 俄