2015-12-22 42 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

相关问题