【问题标题】:Swift unwind segue in viewWillDisappear on NavigationBar back button clicked点击导航栏后退按钮上的 viewWillDisappear 中的 Swift 展开 segue
【发布时间】:2018-12-18 15:17:05
【问题描述】:

我正在尝试在 viewWillDisappear 函数中使用 unwind segue 更改标签文本。每次调用 viewWillDisappear 函数时,它都会自动跳过我的 unwind segue 行而不是执行它。

我正在使用 Xcode 9 和 Swift 4.2

这些是我的代码:

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

我的第二页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)
//    }

}

这是我的故事板配置的图像 (对于 unwind segue 连接,我 ctrl+拖动 View Controller 图标 gamePageViewController 中的退出图标)

如前所述,我无法让 performSegue 在viewWillDisappear 中运行。 我在这里想要实现的是,当我单击 NavigationBar 上的后退按钮时,viewWillDisappear 将拦截并执行对调用 unwindFromGame 并更改 mainLabel 的主 ViewController 的展开 segue。

gameViewController.swift 的代码中,您会注意到我已经注释掉了didMove(toParent)。使用这种方法,我可以让我的performSegue 运行,它成功地从gamePageViewController 检索到abc 变量,但问题是它加载了页面但没有等待我在后退按钮上的提示。相反,它会自动运行 didMove(toParent) 并将我发送回主屏幕,并编辑 mainLabel。我也尝试过willMove(toParent),得到了同样的结果。

我的问题是:

我如何让viewWillDisappear 中的performSegue 运行?

这是与 iPhone X / iPhone Xs Max 相关的问题吗?

使用didMove(toParent)willMove(toParent),如何让它等待返回按钮上的提示?

假设它无法与 NavigationBar Back Button 一起使用。自定义 NavigationBar Back Button 会达到预期的效果吗?如果是这样,我该怎么做?

您是否建议切换到 Swift 4 而不是 4.2?

非常感谢。

【问题讨论】:

    标签: swift xcode segue


    【解决方案1】:

    让我们尝试使用委托模式而不是使用 unwind segue。

    首先为您的gamePageViewController 创建委托协议并声明发送balanceVariables 的函数

    protocol GamePageDelegate {
        func sendBalVariable(_ variable: balanceVariables)  
    }
    

    现在在您的 gamePageViewController 中创建 delegate 变量

    class gamePageViewController: UIViewController {
    
        var delegate: GamePageDelegate?
        ...
    }
    

    然后将此委托实现到您的ViewController 并声明当您在委托上调用此方法时会发生什么

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

    现在覆盖ViewController 中的prepare(for:sender:) 并将目的地的delegate 设置为self(如果segue 的标识符与ViewControllergamePageViewController 之间的segue 的标识符匹配

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "yourIdentifier" {
            let destinationVC = segue.destination as! gamePageViewController
            destinationVC.delegate = self
        }
    }
    

    最后在你的 gamePageViewController 调用方法中,当视图消失并且 ass 参数传递 balVariables

    override func viewWillDisappear(_ animated: Bool) {
        delegate?.sendBalVariable(balVariables)
    }
    

    【讨论】:

    • @StevenStuu 不要使用任何 unwind segues,使用我写的。 "yourIdentifier" 是从ViewController 到第二个的标识符
    • “你的标识符”应该是什么?行destinationVC.delegate = self 给了我一个错误:'UIViewController' 类型的值没有成员'delegate'
    • 你看到故事板中第一个和第二个 VC 之间的这个箭头了吗?单击它,在右侧您将看到文本框,并在那里写下 yourIndetifier
    • 我在情节提要的主 VC 和第二个 VC 之间的 segue 中添加了一个标识符,但错误仍然存​​在。
    • @StevenStuu,您是否按照我的描述覆盖了 prepare 方法?
    猜你喜欢
    • 2021-09-29
    • 1970-01-01
    • 2014-10-11
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多