简体   繁体   English

协议代表可快速访问多个视图

[英]protocol delegates in swift to multiple views

I am trying to learn all I can about delegates. 我正在尝试学习有关代表的一切。 In this example the main page is called PagesTableViewController. 在此示例中,主页称为PagesTableViewController。 When user clicks Page 1, it takes the to DetailsViewController. 当用户单击页面1时,它将转到DetailsViewController。 When you fill in label you go back to PagesTableViewController. 填写标签后,您将返回到PagesTableViewController。 then when Button is pushed it takes you to PrintViewController and shows the label filled in from DetailsViewController. 然后,当按下Button时,将带您到PrintViewController并显示DetailsViewController中填写的标签。 I have been trying tutorials and something in the code I must be doing wrong. 我一直在尝试教程,并且代码中的某些内容我一定做错了。

Here is my view 这是我的看法

在此处输入图片说明

Here is code for PagesTableView 这是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 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)

    }
}

PrintViewController PrintViewController

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)

    }

}

And Lastly my protocol. 最后是我的协议。 File On on swift file 快速打开文件

import Foundation

protocol basicChildInfo {
    func userEnteredChildInfo(data: String)
}

My guess is that the delegate on DetailsViewController never gets set. 我的猜测是DetailsViewController上的委托永远不会被设置。 Here's the sequence of your UI's control flow (as far as I understand it): 这是您的UI控制流程的顺序(据我了解):

  1. a new DetailsViewController is created and presented 创建并显示一个新的DetailsViewController
  2. the user enters text 用户输入文字
  3. the user taps the Save button 用户点击“保存”按钮
  4. DetailsViewController informs its delegate about the text and dismisses itself, thus getting deleted DetailsViewController通知其委托人有关该文本的信息并关闭自身,从而被删除
  5. a new PrintViewController is created and presented 创建并显示一个新的PrintViewController

So at the time when DetailsViewController wants to inform its delegate about the entered value, that delegate has not yet been set; 因此,在DetailsViewController想要将其输入值通知给其委托人时,该委托人尚未设置。 actually the PrintViewController does not even exist at this time. 实际上, PrintViewController甚至不存在。

What's worse, the code in PrintViewController 's prepare-for-segue most likely never gets called because there is no segue from the Print VC to the Details VC, and this method only is run when a segue-based transition occurs. 更糟糕的是,由于没有从Print VC到Details VC的segue,因此很有可能永远不会调用PrintViewController -segue中的代码,并且仅在发生基于segue的过渡时才运行此方法。


So, coming back to the problem you want to solve: I suggest that you... 因此,回到您要解决的问题:我建议您...

  • let PagesTableViewController conform to the delegate protocol and set it as delegate when DetailsViewController is presented PagesTableViewController符合委托协议,并在出现DetailsViewController时将其设置为委托
  • in the delegate callback, store the entered data in a member variable of PagesTableViewController 在委托回调中,将输入的数据存储在PagesTableViewController的成员变量中
  • when PrintViewController is presented, set the value stored in that member var on a property of PrintViewController 当显示PrintViewController时,在PrintViewController的属性上设置存储在该成员var中的PrintViewController

So both actions -- setting the delegate on DetailsViewController and configuring the entered text on PrintViewController -- go into PrintViewController 's prepare-for-segue: 因此,这两项操作-在DetailsViewController上设置委托并在PrintViewController上配置输入的文本-进入PrintViewController “准备进行搜索”:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM