2016-08-21 109 views
3

我想使用協議在模型和視圖之間進行雙向綁定。 我做到了通過創建3個協議: BoundableView.swift在Swift中查看模型綁定

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

BoundableModel.swift

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

ViewModelUpdater.swift

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

,然後在MVC類遵守這些協議

View.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

你會遇到TableViewCells的問題是,他們是「重用」。 TableView控制器僅創建足夠的單元格來填充其視圖。在您滾動時,從頂部消失的細胞在底部「重新使用」(有點像傳送帶)。由於它們的設計方式,將每個單元格綁定到特定的模型元素並不合適。 – tebs1200

回答

0

UITableViews工作,就可以適用於所有的細胞中的ViewModels /更新程序,甚至是尚不可見的那些陣列。

根據您需要填充單元格的數據,如果一次加載所有內容會損害性能或導致高內存使用率,則可能需要使用某種緩存機制,但這是針對每種情況的。

一些代碼來說明我的意思:

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 
    } 
}