Reputation: 63
I'm trying to change a label text with unwind segue in viewWillDisappear function. Every time the viewWillDisappear function is called, it automatically skips my unwind segue line instead of executing it.
I'm using Xcode 9 and Swift 4.2
These are my codes:
main page ViewController.swift
import UIKit
import Foundation
struct globalConstant {
let lostMessage : String = "You Lost!"
let welcomeMessage : String = "WELCOME"
let playAgainMessage : String = "Play again"
let resumeMessage : String = "Resume"
let pausedMessage : String = "Game is paused"
let playMessage : String = "Play Game"
}
class ViewController: UIViewController {
var globalConst = globalConstant()
var labelValue : String!
//start Outlet
@IBOutlet weak var mainLabel: UILabel!
@IBOutlet weak var startButton: UIButton!
//end Outlet
@IBAction func unwindFromGame(_ sender: UIStoryboardSegue){
let gameController = sender.source as? gamePageViewController
if (gameController?.balVariables.balanceValue)! <= 0{
mainLabel.text = gameController?.balVariables.abc
}
else {
mainLabel.text = self.globalConst.pausedMessage
}
}
}
my second page gamePageViewController.swift
import UIKit
import Foundation
struct balanceVariables {
//declare var start
var initBalance : Int = 500
var balanceValue : Int = 0
let abc = "abc"
//declare var end
}
class gamePageViewController: UIViewController {
// override func addChild(_ gamePageViewController: UIViewController) {
// }
@IBOutlet weak var valueHolder: UILabel!
var balVariables = balanceVariables()
override func viewDidLoad() {
super.viewDidLoad()
//run on page load
if balVariables.balanceValue <= 0 {
balVariables.balanceValue = balVariables.initBalance
valueHolder.text = String(balVariables.balanceValue)
}else{
balVariables.balanceValue = balVariables.balanceValue
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
performSegue(withIdentifier: "unwindFromGame", sender: self)
}
// override func didMove(toParent ViewController: UIViewController?){
// performSegue(withIdentifier: "unwindFromGame", sender: self)
// }
}
Here is the image of my storyboard configuration
(for the unwind segue connection, I ctrl+dragged the View Controller icon
to exit icon in gamePageViewController
)
As mentioned, I couldn't get performSegue to run in viewWillDisappear
.
What I'm trying to achieve here is when I click the back button on NavigationBar, the viewWillDisappear
will intercept and perform an unwind segue to the main ViewController which calls unwindFromGame
and changes mainLabel
.
From the code in gameViewController.swift
, you'll notice that I have commented out didMove(toParent)
. Using this method, I could get my performSegue
to run and it successfully retrieved the abc
variable from gamePageViewController
but the problem is that it loaded the page but didn't wait for my prompt on the back button. Instead it automatically ran didMove(toParent)
and sent me back to my main screen with mainLabel
edited. I've tried willMove(toParent)
as well and I achieved the same result.
My questions are :
How do I get performSegue
in viewWillDisappear
to run?
Is this an iPhone X / iPhone Xs Max related issue?
Using didMove(toParent)
or willMove(toParent)
, how do I get it to wait for my prompt on the back button?
Let's say it's not possible to get it to work with NavigationBar Back Button. Will a custom NavigationBar Back Button achieve expected result? If so, how should I do it?
Do you recommend switching to Swift 4 instead of 4.2?
Thank you very much.
Upvotes: 0
Views: 617
Reputation: 11140
Let's try it with delegate pattern not with using unwind segue.
Firste create delegate protocol for your gamePageViewController
and declare function for sending balanceVariables
protocol GamePageDelegate {
func sendBalVariable(_ variable: balanceVariables)
}
now create delegate
variable in your gamePageViewController
class gamePageViewController: UIViewController {
var delegate: GamePageDelegate?
...
}
Then implement this delegate to your ViewController
and declare what should happen when you call this method on delegate
class ViewController: UIViewController, GamePageDelegate {
...
func sendBalVariable(_ variable: balanceVariables) {
if variable.balanceValue <= 0 {
mainLabel.text = variables.abc
} else {
mainLabel.text = self.globalConst.pausedMessage
}
/* mainLabel.text = variable.balanceValue <= 0 ? variables.abc : self.globalConst.pausedMessage */
}
}
now override prepare(for:sender:)
in your ViewController
and set destination's delegate
as self
(if segue's identifier matching with identifier of your segue between ViewController
and gamePageViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "yourIdentifier" {
let destinationVC = segue.destination as! gamePageViewController
destinationVC.delegate = self
}
}
Finally in your gamePageViewController
call method on delegate when view will disappear and ass parameter pass balVariables
override func viewWillDisappear(_ animated: Bool) {
delegate?.sendBalVariable(balVariables)
}
Upvotes: 1