在TableViewController和ViewController之间委派

问题描述 投票:0回答:3

我正处于iOS开发的第一周,并且已经陷入了在视图控制器之间传递数据的问题。我的设置包含一个视图,VC中有一个按钮,还有一个容器视图(没有关联的视图控制器)。容器视图具有嵌入式Segue到TableView和TableViewController。该表有6行,每行都有一个步进器,可以更改相关行上的文本视图的值。我想要做的是当我按下主视图上的按钮时收集所有文本视图的值。

我正在尝试使用委托来执行此操作,但是当我按下按钮时,返回的值始终为零。我认为问题是因为VC没有通过prepareForSegue函数传递给表视图控制器,但我不确定为什么?可能与控制器的加载顺序有关吗?

import UIKit

class PredictionViewController: UIViewController, PredictionDelegate {

    var predictionData: String!

    @IBOutlet weak var messageTextBox: UITextView!
    @IBOutlet weak var predictionSubmitButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        self.messageTextBox.isEditable = false
    }

    override func viewDidAppear(_ animated: Bool) {

    }

    func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
        if (segue.identifier == "predictionSegue") {
            // pass data to next view
            let vc = segue.destination as! PredictionsTableViewController
            vc.predictionHomeDelegate = self
        }
    }

    func receiveData(with data: String) {
        predictionData = data
        print(predictionData)
    }

    @IBAction func predictionSubmitButtonAction(_ sender: UIButton) {
        print(predictionData)
    }

}

TableViewController :(剥离到最小)

import UIKit

protocol PredictionDelegate: class {
    func receiveData(with data: String)
}

class PredictionsTableViewController: UITableViewController, PredictionDelegate {

    weak var predictionHomeDelegate: PredictionDelegate?

    @IBOutlet weak var homeTeamScore1: UITextView!
    @IBOutlet weak var homeTeamStepper1: UIStepper!

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func viewDidAppear(_ animated: Bool) {

    }

    func getPredictionList() {
        //does some stuff
        self.passDataBackwards()
    }

    func receiveData(with data: String) {}

    func passDataBackwards() {
        let data = "{\"score\":\"1\"}"
        predictionHomeDelegate?.receiveData(with: data)
    }

    @IBAction func homeTeamStepper1Action(_ sender: UIStepper) {

        let score = Int(sender.value).description
        homeTeamScore1.text = score
        self.passDataBackwards()
    }
}

storyboard view

任何帮助感激不尽!

ios swift
3个回答
1
投票

编辑:

评论后......

你对Protocols和Delegates有错误的想法。这里不需要它们。

相反,在您的“home”VC中,获取对嵌入式VC的引用。然后,在嵌入式VC中添加一个函数,您可以调用该函数来获取其数据。

enter image description here

// "home" view controller
class PredictionViewController: UIViewController {

    // this will be a reference to the embedded view controller
    var embeddedVC: PredictionsTableViewController?

    @IBAction func getDataButtonTapped(_ sender: Any) {
        if let tableData = embeddedVC?.getMyData() {
            print("Result: \(tableData)")
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier == "predictionSegue") {
            if let vc = segue.destination as? PredictionsTableViewController {
                // get a reference to the embedded VC
                self.embeddedVC = vc
            }
        }
    }

}

// embedded view controller
class PredictionsTableViewController: UIViewController {

    var numTaps = 0

    func getMyData() -> String {
        return "\(numTaps)"
    }

    @IBAction func didTap(_ sender: Any) {
        numTaps += 1
    }

}

你很亲密,但有几个错误......

这是一个非常非常简单的例子。使用容器查看控制器,该控制器具有带按钮的视图控制器。

码:

import UIKit

// your protocol    
protocol PredictionDelegate: class {
    func receiveData(with data: String)
}

// embedded view controller
// NOTE: this should NOT include PredictionDelegate
class PredictionsTableViewController: UIViewController {

    weak var predictionHomeDelegate: PredictionDelegate?

    @IBAction func didTap(_ sender: Any) {
        // on button tap, "send data back"
        predictionHomeDelegate?.receiveData(with: "Test")
    }

}

// "home" view controller
// NOTE: this DOES include PredictionDelegate
class PredictionViewController: UIViewController, PredictionDelegate {

    func receiveData(with data: String) {
        print(data)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier == "predictionSegue") {
            if let vc = segue.destination as? PredictionsTableViewController {
                // set self as the delegate of the embedded PredictionsTableViewController
                vc.predictionHomeDelegate = self
            }
        }
    }

}

笔记:

  • 不要在嵌入式视图控制器中包含func receiveData(with data: String) {}
  • 不要将PredictionDelegate分配给嵌入式视图控制器

0
投票

您需要将segue挂钩到vc本身而不是单元格并使用

self.performSegue(withIdentifier: "predictionSegue", sender: nil)

0
投票

由于这些是两个独立的屏幕,我不太确定第一个视图控制器上的按钮从第二个提交数据是多么有意义,按钮不仅可以在第二个上。如果由于某种原因它不能通过向第一个视图控制器添加一个公共变量并向第二个视图控制器添加另一个准备方法来向第二个视图控制器传递数据,就像你在添加委托。

© www.soinside.com 2019 - 2024. All rights reserved.