Reputation: 125
I am trying to learn all I can about delegates. In this example the main page is called PagesTableViewController. When user clicks Page 1, it takes the to DetailsViewController. When you fill in label you go back to PagesTableViewController. then when Button is pushed it takes you to PrintViewController and shows the label filled in from 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
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)
}
}
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)
}
Upvotes: 0
Views: 1601
Reputation: 6065
My guess is that the delegate on DetailsViewController
never gets set. Here's the sequence of your UI's control flow (as far as I understand it):
DetailsViewController
is created and presentedDetailsViewController
informs its delegate about the text and dismisses itself, thus getting deletedPrintViewController
is created and presentedSo at the time when DetailsViewController
wants to inform its delegate about the entered value, that delegate has not yet been set; actually the PrintViewController
does not even exist at this time.
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.
So, coming back to the problem you want to solve: I suggest that you...
PagesTableViewController
conform to the delegate protocol and set it as delegate when DetailsViewController
is presentedPagesTableViewController
PrintViewController
is presented, set the value stored in that member var on a property of PrintViewController
So both actions -- setting the delegate on DetailsViewController
and configuring the entered text on PrintViewController
-- go into PrintViewController
's 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
}
}
Upvotes: 1