我正在尽我所能地了解代表们。在本例中,主页面称为PagesTableViewController。当用户单击第1页时,将使用to detailsView控件。填写标签后,返回PageStableviewControl。然后,当按下按钮时,它将带您到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)
}
}
最后是我的协议。在swift文件上存档
import Foundation
protocol basicChildInfo {
func userEnteredChildInfo(data: String)
}
最佳答案
我的猜测是,DetailsViewController
上的代理永远不会被设置。以下是用户界面控制流的顺序(据我所知):
创建并呈现一个新的DetailsViewController
用户输入文本
用户点击保存按钮DetailsViewController
通知其代理有关文本并自行退出,从而被删除
创建并呈现一个新的PrintViewController
因此,当DetailsViewController
想要告知其委托的输入值时,该委托还没有被设置;实际上,PrintViewController
甚至在此时还不存在。
更糟糕的是,prepare for segue中的代码很可能永远不会被调用,因为从Print VC到Details VC中没有segue,并且此方法只在发生基于segue的转换时运行。
所以,回到你想解决的问题:我建议你。。。
让PrintViewController
符合委托协议,并在出现PagesTableViewController
时将其设置为委托
在委托回调中,将输入的数据存储在DetailsViewController
的成员变量中
当出现PagesTableViewController
时,在属性PrintViewController
上设置存储在该成员var中的值
因此,这两个操作——将代理设置为PrintViewController
并将输入的文本配置为DetailsViewController
——都进入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
}
}
关于swift - 协议(protocol)代表可快速访问多个 View ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48477870/