Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
swift中的协议委托到多个视图_Swift_View_Controller_Delegates_Protocols - Fatal编程技术网

swift中的协议委托到多个视图

swift中的协议委托到多个视图,swift,view,controller,delegates,protocols,Swift,View,Controller,Delegates,Protocols,我正在尽我所能学习有关代表的知识。在本例中,主页称为PagesTableViewController。当用户单击第1页时,它将转到DetailsViewController。填写标签后,返回PagesTableViewController。然后,当按下按钮时,它会将您带到PrintViewController,并显示从DetailsViewController填写的标签。我一直在尝试教程和一些代码,我一定是做错了 这是我的看法 下面是PagesTableView的代码 import UIKit

我正在尽我所能学习有关代表的知识。在本例中,主页称为PagesTableViewController。当用户单击第1页时,它将转到DetailsViewController。填写标签后,返回PagesTableViewController。然后,当按下按钮时,它会将您带到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" {

        }
    }

}
详细信息查看控制器

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)

    }

}
PrintViewController

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)

    }

}
最后是我的协议。存档于swift文件

import Foundation

protocol basicChildInfo {
    func userEnteredChildInfo(data: String)
}

我猜,
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
    的准备阶段:

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

    你的问题是什么?我无法从detailsviewcontroller上的文本字段中获取要显示在我的printviewcontroller中的信息,也不确定我是否已关闭。对不起,我上周生病了。。我明白你的意思。我只是有一个艰难的时间与这个。因此,我应该在PagesTableViewController上启动委托,然后在savebtn函数中调用它。那就用打印页上的“准备”部分吧?答案里都有,我不知道怎么说得更清楚。如果你有一个特定的问题,你可以问,但是你在评论中的后续问题在我提供的分步指南中得到了非常准确的回答。我错放了一些代码。我现在让它工作了!非常感谢你的帮助。我将用这个方法练习一段时间,直到我更好地掌握它!