2016-08-21 12 views
3

私は、プロトコルを使用してモデルとビューの間に双方向バインディングを作成しようとしています。 私は3つのプロトコル作成することによって、それをやった:MVCのクラスでこれらのプロトコルに準拠しViewModelUpdater.swiftSwiftでモデルのバインディングを表示

BoundableModel.swift

protocol BoundableModel { 
    var updater: ViewModelUpdater? {get set} 
} 

その後、

protocol ViewModelUpdater { 
    func updateModel(view: BoundableView) 
    func updateView(model: BoundableModel) 
} 

とを BoundableView.swift

protocol BoundableView { 
    var updater: ViewModelUpdater? {get set} 
} 

表示.swift

class View: UIView,BoundableView { 

    var updater :ViewModelUpdater? = nil 

    @IBOutlet var nameTextField: UITextField! 
    @IBOutlet var valueTextField: UITextField! 

    @IBAction func valueChanged(_ sender: AnyObject) { 
    updater?.updateModel(view: self) 
    } 
} 

Model.swift

class Model : BoundableModel{ 
    var updater: ViewModelUpdater? = nil 

    var name:String { 
     didSet { 
      if let updater = updater{ 
       updater.updateView(model: self) 
       print(self) 
      } 
     } 
    } 
    var value:Int { 
     didSet { 
      if let updater = updater{ 
       updater.updateView(model: self) 
       print(self) 
      } 
     } 
    } 
    init(name:String,value:Int) { 
     self.name = name 
     self.value = value 
    } 
} 

Controller.swift

class Controller: UIViewController,ViewModelUpdater { 

    var boundableModel = Model(name : "hello", value: 5) 

    @IBOutlet var boundableView: View! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     boundableModel.updater = self 
     boundableView.updater = self 

    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 

    } 


    func updateModel(view: BoundableView) { 
     let view = view as! View 
     boundableModel.name = view.nameTextField.text! 
     boundableModel.value = Int(view.valueTextField.text!)! 

    } 

    func updateView(model: BoundableModel) { 
     let model = model as! Model 
     boundableView.nameTextField.text = model.name 
     boundableView.valueTextField.text = String(model.value) 

    } 
} 

私がモデルに例のテーブルセルにバインドするとき、私はセルがあるかわからないので、問題は、来ます配列内のどのモデルにバインドされています。これを行う他の方法はありますか?

+1

問題は、彼らが「再利用」しているということです。 TableViewコントローラは、ビューを埋めるだけの十分なセルを作成します。あなたがスクロールすると、上から消える細胞は底部に「再利用」されます(コンベアベルトのようなものです)。設計方法によって、各セルを特定のモデル要素にバインドすることは実際には適切ではありません。 – tebs1200

答えて

0

UITableViewsを使用すると、表示されていないセルでも、すべてのセルに対してviewModels/updatersの配列を保持できます。

セルを取り込む必要があるデータによっては、すべてを一度に読み込むとパフォーマンスが低下したり、メモリ使用量が高くなったりすることがありますが、何らかのキャッシュメカニズムを使用する必要があります。

私が何を意味するか示すためにいくつかのコード:あなたはTableViewCellsで発生するだろう

class MyBindableCell: UITableViewCell, BoundableView { 
    var updater: ViewModelUpdater? = nil 
    //... 
} 

class Controller: UIViewController { 

    var cellViewModels: [BoundableModel] 
    var cellViewModelUpdaters: [ViewModelUpdater] 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     //... 
     //initialize cellViewModels and viewModelUpdaters 
     //... 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("cellId", forIndexPath: indexPath) as! MyBindableCell 
     cell.updater = viewModelUpdaters[indexPath.row] 
     cell.updater?.updateView(cellViewModels[indexPath.row]) 
     return cell 
    } 
} 
関連する問題