2015-12-22 40 views
0

我有UITableView與兩個靜態單元格。當我填充單元格中的文本字段時,每個單元格都具有自定義類並獨立驗證帳戶名稱。 (我得到的這部分代碼是我的,我不允許重寫它)。如果驗證對於委託是正確的,則單元委託有關更改(SocialFeedSelectCellDelegate)。本來,這個tableView只出現在SignUpViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate, SocialFeedSelectCellDelegateiOS中這種情況的最佳設計解決方案是什麼?

問題:同UITableView應該出現在兩個不同的地方(SignUpViewControllerSettingsViewController)。 SignUpViewControllerSettingsViewController也應該瞭解帳戶驗證是否成功。

我試過:我爲兩個單元格的tableView創建了SocialFeedTableViewController: UITableViewController, SocialFeedSelectCellDelegate。將SocialFeedTableViewController中的視圖設置爲容器視圖SignUpViewControllerSettingsViewController。我使用第二個代表團(從SocialFeedTVC到註冊和設置)來通知註冊和設置有關驗證更改。我認爲這是一個壞主意,因爲雙重授權。隊友說我很難理解。

問題:問題的最佳和簡單的設計解決方案是什麼? enter image description here

+0

根據帳戶驗證成功或失敗,此同一表是否顯示兩個viewController的不同數據?爲什麼不是兩個不同的tableView?另外,委託是溝通兩個viewController的好方法。 – nikhil84

+0

@ nikhil84 tableView爲兩個viewControllers委託兩個方法(accountValidated(accountType:String,accountName:String),accountEditing(accountType:String,accountName:String) 也許兩個不​​同的tableView會很好。但雙重代表團仍然會在這種情況下,是嗎? – Simankov

+0

您可以使用兩個控制器所需的方法創建一個通用委託類。 – nikhil84

回答

1

爲什麼雙重委託是一個問題?據我所知,你有2個表格視圖,每個控制器1個。然後每個控制器將委託設置爲每個表視圖爲self。即使不是,在運行時更改對象的委託也是很常見的。爲了能夠將消息轉發到2個或更多對象,使用相同協議的2個代表屬性也是正常的。

還有很多選擇。您可以使用默認的通知中心,並且能夠以這種方式轉發消息。唯一不好的是你需要明確地從通知中心辭去通知監聽器。

你的情況中另一個更有趣的過程是創建一個模型(一個類),它保存來自表視圖的數據並且還實現了單元格中的協議。然後應將該模型作爲屬性轉發給新的視圖控制器。如果視圖控制器仍然需要刷新超出表視圖,那麼模型應該包含視圖控制器本身的另一個協議。

採取這樣的事情,例如:

protocol ModelProtocol: NSObjectProtocol { 
    func cellDidUpdateText(cell: DelegateSystem.Model.MyCell, text: String?) 
} 

class DelegateSystem { 
    class Model: NSObject, UITableViewDelegate, UITableViewDataSource, ModelProtocol { 

     // My custom cell class 
     class MyCell: UITableViewCell { 
      weak var modelDelegate: ModelProtocol? 
      var indexPath: NSIndexPath? 

      func onTextChanged(field: UITextField) { // just an example 
       modelDelegate?.cellDidUpdateText(self, text: field.text) // call the cell delegate 
      } 
     } 

     // some model values 
     var firstTextInput: String? 
     var secondTextInput: String? 

     // a delegate method from a custom protocol 
     func cellDidUpdateText(cell: DelegateSystem.Model.MyCell, text: String?) { 
      // update the appropriate text 
      if cell.indexPath?.row == 0 { 
       self.firstTextInput = text 
      } else { 
       self.secondTextInput = text 
      } 
     } 

     // table view data source 
     func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
      return 2 
     } 
     func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
      let cell = MyCell() // create custom cell 
      cell.indexPath = indexPath // We want to keep track of the cell index path 
      // assign from appropriate text 
      if cell.indexPath?.row == 0 { 
       cell.textLabel?.text = self.firstTextInput 
      } else { 
       cell.textLabel?.text = self.secondTextInput 
      } 
      cell.modelDelegate = self // set the delegate 
      return cell 
     } 
    } 

    // The first view controller class 
    class FirstViewController: UIViewController { 
     var tableView: UITableView? // most likely from storyboard 
     let model = Model() // generate the new model 

     override func viewDidLoad() { 
      super.viewDidLoad() 
      refresh() // refresh when first loaded 
     } 
     override func viewDidAppear(animated: Bool) { 
      super.viewDidAppear(animated) 
      refresh() // Refresh each time the view appears. This will include when second view controller is popped 
     } 

     func refresh() { 
      if let tableView = self.tableView { 
       tableView.delegate = model // use the model as a delegate 
       tableView.dataSource = model // use the model as a data source 
       tableView.reloadData() // refresh the view 
      } 
     } 

     // probably from some button or keyboard done pressed 
     func presentSecondController() { 
      let controller = SecondViewController() // create the controller 
      controller.model = model // assign the same model 
      self.navigationController?.pushViewController(controller, animated: true) // push it 
     } 
    } 

    // The second view controller class 
    class SecondViewController: UIViewController { 
     var tableView: UITableView? // most likely from storyboard 
     var model: Model? // the model assigned from the previous view controller 

     override func viewDidLoad() { 
      super.viewDidLoad() 
      refresh() // refresh when first loaded 
     } 
     override func viewDidAppear(animated: Bool) { 
      super.viewDidAppear(animated) 
      refresh() // Refresh each time the view appears. This will include when third view controller is popped 
     } 

     func refresh() { 
      if let tableView = self.tableView { 
       tableView.delegate = model // use the model as a delegate 
       tableView.dataSource = model // use the model as a data source 
       tableView.reloadData() // refresh the view 
      } 
     } 

     // from back button for instance 
     func goBack() { 
      self.navigationController?.popViewControllerAnimated(true) 
     } 
    } 
} 

在這裏,2個視圖控制器將與這也實現了表視圖協議相同的對象進行通信。我不建議你把所有這些放在一個文件中,但是你可以看到兩個視圖控制器都非常乾淨,模型接管了所有繁重的工作。該模型可能有另一個委託,然後由視圖控制器自己使用它來轉發其他信息。當視圖出現時,控制器應該從模型中「偷走」代表插槽。

我希望這可以幫助你理解代表不是一維的,可以用它們完成很多事情。

+0

好方法。最後,我使用了UITableView,它也是xib中的委託和數據源以及UITableViewCell .TableView還將其更改委託給設置在didSet中的AccountsChangeProtocol委託。看起來不好,但很簡單,沒有使用segues和遏制的意見 – Simankov

相關問題