迅速将协议委托给多个视图

Posted

技术标签:

【中文标题】迅速将协议委托给多个视图【英文标题】:protocol delegates in swift to multiple views 【发布时间】:2018-01-27 16:27:36 【问题描述】:

我正在尽我所能了解代表。在此示例中,主页面称为 PagesTableViewController。当用户单击第 1 页时,它会转到 DetailsViewController。当您填写标签时,您将返回 PagesTableViewController。然后当按下 Button 时,它会将您带到 PrintViewController 并显示从 DetailsViewController 填写的标签。我一直在尝试教程和代码中的某些内容,我一定做错了。

这是我的看法

这是 PagesTableView 的代码

import UIKit

class PagesTableViewController: UIViewController 

    let pages = ["Page 1","Page 2","Page 3"]

    @IBOutlet weak var pagesTableView: UITableView!


    override func viewDidLoad() 
        super.viewDidLoad()

        pagesTableView.dataSource = self

    

    @IBAction func printBtnPressed(_ sender: Any) 

    




extension PagesTableViewController: UITableViewDataSource 

    // MARK: - Table view data source

     func numberOfSections(in tableView: UITableView) -> Int 
        // #warning Incomplete implementation, return the number of sections
        return 1
    

     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        // #warning Incomplete implementation, return the number of rows
        return pages.count
    

      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
     let cell = tableView.dequeueReusableCell(withIdentifier: "PagesCell", for: indexPath)

     cell.textLabel?.text = pages[indexPath.row]

     return cell
     

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
        if segue.identifier == "DetailsViewSegue" 

        
    


DetailsViewController

import UIKit

class DetailsViewController: UIViewController 

    @IBOutlet weak var detailsTextField: UITextField!

    var childDelegate: basicChildInfo?

    override func viewDidLoad() 
        super.viewDidLoad()

    

    @IBAction func cancelBtnPressed(_ sender: Any) 
        dismiss(animated: true, completion: nil)
    

    @IBAction func saveBtnPressed(_ sender: Any) 

        let data = detailsTextField.text
        childDelegate?.userEnteredChildInfo(data: data!)
        dismiss(animated: true, completion: nil)

    

打印视图控制器

import UIKit

class PrintViewController: UIViewController, basicChildInfo 

    @IBOutlet weak var printLabelOne: UILabel!


    override func viewDidLoad() 
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    

    //protocol func pulled from child info -- Data from child info
    func userEnteredChildInfo(data: String) 
        printLabelOne.text = data
    

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
        if segue.identifier == "PrintSegue" 
            let childInfoVC: DetailsViewController = segue.destination as! DetailsViewController
            childInfoVC.childDelegate = self
        
    

    @IBAction func printBtnPressed(_ sender: Any) 

        print("Printing File")
        dismiss(animated: true, completion: nil)

    


最后是我的协议。快速文件上的文件打开

import Foundation

protocol basicChildInfo 
    func userEnteredChildInfo(data: String)

【问题讨论】:

你有什么问题? 我无法从 detailsviewcontroller 上的文本字段中获取该信息以显示在我的 printviewcontroller 中,并且不确定我是否关闭 【参考方案1】:

我的猜测是DetailsViewController 上的委托永远不会被设置。这是您的 UI 控制流的顺序(据我所知):

    创建并呈现一个新的DetailsViewController 用户输入文字 用户点击保存按钮 DetailsViewController 将文本通知其代表并关闭自己,从而被删除 创建并呈现一个新的PrintViewController

因此,当DetailsViewController 想要通知其委托有关输入的值时,该委托尚未设置;实际上,此时PrintViewController 甚至都不存在。

更糟糕的是,PrintViewController 的 prepare-for-segue 中的代码很可能永远不会被调用,因为没有从 Print VC 到 Details VC 的 segue,并且此方法仅在基于 segue 的转换时运行发生。


所以,回到你要解决的问题:我建议你...

PagesTableViewController符合委托协议,并在DetailsViewController出现时将其设置为委托 在委托回调中,将输入的数据存储在PagesTableViewController的成员变量中 当出现PrintViewController 时,将存储在该成员变量中的值设置为PrintViewController 的属性

所以这两个动作——在DetailsViewController上设置代理和在PrintViewController上配置输入的文本——进入PrintViewController的prepare-for-segue:

class PagesTableViewController: UIViewController, BasicChildInfo 
  private var userText: String? = nil

  func userEnteredChildInfo(data: String) 
    userText.text = data
  

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
      if segue.identifier == "DetailsViewSegue" 
        (segue.destination as! DetailsViewController).childDelegate = self
      
      else if  segue.identifier == "PrintSegue" 
        (segue.destination as! PrintViewController).userText = self.userText
      
  

【讨论】:

对不起,我上周生病了。我明白你在说什么。我只是很难处理这个。所以我应该在 PagesTableViewController 上启动委托,然后在 savebtn 函数中调用它。然后在打印页面上使用prepare segue? 答案都在,不知道怎么讲清楚。如果您有特定问题可以提出,但我提供的分步指南几乎完全回答了您在评论中的后续问题。 我放错了一些代码。我现在可以工作了!非常感谢你的帮助。我会用这个方法练习一段时间,直到我掌握得更好!

以上是关于迅速将协议委托给多个视图的主要内容,如果未能解决你的问题,请参考以下文章

未为 UITextView 触发委托协议功能

调用具有多个子视图层次结构的协议方法

如何将多个委托添加到我的视图控制器?

如何使用委托将数据从多个视图控制器传递回根视图控制器? IOS 7

如何跨多个视图控制器引用同一个类的实例?

Swift使用委托实现多个协议