在呈现的 UIViewController 关闭后刷新父 UIViewController

Refresh parent UIViewController after presented UIViewController dismisses

我有一个 MainVC 用于 select 要编辑哪个元素,它由四个按钮和四个标签组成。当你 select 一个按钮时,它会传递按钮的 ID(通过 prepare)并执行 segue(Present Modally)。用户输入数据后,按下“保存”按钮,它将数据应用于全局变量并调用 self.dismiss.

当我们回到 MainVC 时,问题就出现了,它没有更新标签。

我有一个函数可以创建字符串并将其应用于 UILabel.text 并尝试将其添加到 viewDidLoad并且 viewWillAppear 没有成功,所以我添加了一个“刷新”按钮来调用该函数并且可以正常工作,但如果该死的东西会自动更新,我会更喜欢它。

主要VC代码:

//
//  ViewController.swift
//  IBS Club Match Scoring
//
//  Created by Michael Brewer on 2/11/21.
//

import UIKit

var mainVC = ViewController()

class ViewController: UIViewController {
    
    struct GlobalVars {
        static var scoreTarget1 = 0
        static var scoreTarget2 = 0
        static var scoreTarget3 = 0
        static var scoreTarget4 = 0
        static var xCountTarget1 = 0
        static var xCountTarget2 = 0
        static var xCountTarget3 = 0
        static var xCountTarget4 = 0
//        static var matchTotal = "0 - 0X"
//        static var overallScore = 0
//        static var overallXCount = 0
        
//        func updateScores() {
//            var target1ScoreText = "\(ViewController.GlobalVars.scoreTarget1) - \(ViewController.GlobalVars.xCountTarget1)X"
//            var target2ScoreText = "\(ViewController.GlobalVars.scoreTarget2) - \(ViewController.GlobalVars.xCountTarget2)X"
//            var target3ScoreText = "\(ViewController.GlobalVars.scoreTarget3) - \(ViewController.GlobalVars.xCountTarget3)X"
//            var target4ScoreText = "\(ViewController.GlobalVars.scoreTarget4) - \(ViewController.GlobalVars.xCountTarget4)X"
//            ViewController.GlobalVars.overallScore = ViewController.GlobalVars.scoreTarget1 + ViewController.GlobalVars.scoreTarget2 + ViewController.GlobalVars.scoreTarget3 + ViewController.GlobalVars.scoreTarget4
//            ViewController.GlobalVars.overallXCount = ViewController.GlobalVars.xCountTarget1 + ViewController.GlobalVars.xCountTarget2 + ViewController.GlobalVars.xCountTarget3 + ViewController.GlobalVars.xCountTarget4
//            ViewController.GlobalVars.matchTotal = "\(ViewController.GlobalVars.overallScore) - \(ViewController.GlobalVars.overallXCount)X"
//        }
    }
    //Variables
    var whatTargetIsThis = 0
//    var whatTargetWasThis = 0
    var matchTotal = "0 - 0X"
    var overallScore = 0
    var overallXCount = 0
//    var btnID = ""
    
    
    //Upper Display
    @IBOutlet weak var matchTotalLabel: UILabel!
    @IBOutlet weak var matchTotalScore: UILabel!
    
    //Target Scores
    @IBOutlet weak var target1Score: UILabel!
    @IBOutlet weak var target2Score: UILabel!
    @IBOutlet weak var target3Score: UILabel!
    @IBOutlet weak var target4Score: UILabel!
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if(segue.identifier == "enterScoresSeg"){
                let entryVC = segue.destination as! ScoringUI
            entryVC.targetNumber = whatTargetIsThis
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
//        print("this was target number \(whatTargetWasThis)")
       // print(ViewController.GlobalVars.scoreTarget1)
//        updateScores()
    }
    
//    override func viewWillAppear(_ animated: Bool) {
//       // updateScores()
//    }
    
//    override func setNeedsFocusUpdate() {
//        updateScores()
//    }
    
    func updateScores() {
        target1Score.text  = "\(ViewController.GlobalVars.scoreTarget1) - \(ViewController.GlobalVars.xCountTarget1)X"
        target2Score.text = "\(ViewController.GlobalVars.scoreTarget2) - \(ViewController.GlobalVars.xCountTarget2)X"
        target3Score.text = "\(ViewController.GlobalVars.scoreTarget3) - \(ViewController.GlobalVars.xCountTarget3)X"
        target4Score.text = "\(ViewController.GlobalVars.scoreTarget4) - \(ViewController.GlobalVars.xCountTarget4)X"
        overallScore = ViewController.GlobalVars.scoreTarget1 + ViewController.GlobalVars.scoreTarget2 + ViewController.GlobalVars.scoreTarget3 + ViewController.GlobalVars.scoreTarget4
        overallXCount = ViewController.GlobalVars.xCountTarget1 + ViewController.GlobalVars.xCountTarget2 + ViewController.GlobalVars.xCountTarget3 + ViewController.GlobalVars.xCountTarget4
        matchTotalScore.text = "\(overallScore) - \(overallXCount)X"
    }
    
   
    @IBAction func refreshDisplay(_ sender: UIButton) {
        updateScores()
    }
    
    
    // Go-To Target Buttons
    
    @IBAction func targetBtn(_ sender: UIButton) {
        switch sender.titleLabel?.text {
        case "Target 1":
            whatTargetIsThis = 1
        case "Target 2":
            whatTargetIsThis = 2
        case "Target 3":
            whatTargetIsThis = 3
        case "Target 4":
            whatTargetIsThis = 4
        default:
            break
        }
        self.performSegue(withIdentifier: "enterScoresSeg", sender:self)
    }

}

第二个VC代码:

//
//  ScoringUI.swift
//  IBS Club Match Scoring
//
//  Created by Michael Brewer on 2/11/21.
//

import UIKit

class ScoringUI: UIViewController {

    //Variables
    var targetNumber = 0
    var runningScore = 0
    var runningX = 0
    var runningTotal = " "
    var keyPressed = 0
    var addAnX = 0
    var shots = ["-","-","-","-","-"]
    var i = 0
    var shot = ""
    var shotsListed = ""
    //Display boxes for each shot
    @IBOutlet weak var eachShot: UILabel!

    //Display target score
    @IBOutlet weak var targetScore: UILabel!
    @IBOutlet weak var mosesFU: UIImageView!
    
    func sendScoresToMain() {
        
        switch targetNumber {
        case 1:
            ViewController.GlobalVars.scoreTarget1 = runningScore
            ViewController.GlobalVars.xCountTarget1 = runningX
            print("running case 1")
        case 2:
            ViewController.GlobalVars.scoreTarget2 = runningScore
            ViewController.GlobalVars.xCountTarget2 = runningX
        case 3:
            ViewController.GlobalVars.scoreTarget3 = runningScore
            ViewController.GlobalVars.xCountTarget3 = runningX
        case 4:
            ViewController.GlobalVars.scoreTarget4 = runningScore
            ViewController.GlobalVars.xCountTarget4 = runningX
        default:
            break
        }
        
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print(targetNumber)
    }
    
    
    func updateView() {
        if i < 5 {
            runningScore += keyPressed
            runningX += addAnX
            shots[i] = shot
            //Update total score
            if runningScore > 0 && runningX >= 0 {
                runningTotal = "\(runningScore) - \(runningX) X"
            } else {
                runningTotal = "0 - 0X"
            }
            targetScore.text = runningTotal
            shotsListed = "\(shots[0]), \(shots[1]), \(shots[2]), \(shots[3]), \(shots[4])"
            eachShot.text = shotsListed
            if runningScore == 50 {
                mosesFU.alpha = 1
                targetScore.textColor = UIColor.white
            }
            i += 1
        }
    }

    //Keypad to enter scores
    
    @IBAction func buttonX(_ sender: UIButton) {
        keyPressed = 10
        addAnX = 1
        shot = "X"
        updateView()
    }
    @IBAction func button10(_ sender: UIButton) {
        keyPressed = 10
        addAnX = 0
        shot = "10"
        updateView()
    }
    @IBAction func button9(_ sender: UIButton) {
        keyPressed = 9
        addAnX = 0
        shot = "9"
        updateView()
    }
    @IBAction func button8(_ sender: UIButton) {
        keyPressed = 8
        addAnX = 0
        shot = "8"
        updateView()
    }
    @IBAction func button7(_ sender: UIButton) {
        keyPressed = 7
        addAnX = 0
        shot = "7"
        updateView()
    }
    @IBAction func button6(_ sender: UIButton) {
        keyPressed = 6
        addAnX = 0
        shot = "6"
        updateView()
    }
    @IBAction func button5(_ sender: UIButton) {
        keyPressed = 5
        addAnX = 0
        shot = "5"
        updateView()
    }
    @IBAction func button0(_ sender: UIButton) {
        keyPressed = 0
        addAnX = 0
        shot = "0"
        updateView()
    }
    @IBAction func buttonM(_ sender: UIButton) {
        keyPressed = -51
        addAnX = -6
        shot = "M"
        updateView()
    }
    
    @IBAction func resetDisplay(_ sender: UIButton) {
        runningScore = 0
        runningX = 0
        runningTotal = " "
        keyPressed = 0
        addAnX = 0
        shots = ["-","-","-","-","-"]
        i = 0
        shot = ""
        shotsListed = ""
        if runningScore > 0 && runningX >= 0 {
            runningTotal = "\(runningScore) - \(runningX) X"
        } else {
            runningTotal = "0 - 0X"
        }
        targetScore.text = runningTotal
        eachShot.text = shotsListed
        mosesFU.alpha = 0
        targetScore.textColor = UIColor.black
        
    }
    @IBAction func back(_ sender: Any) {
        sendScoresToMain()
        self.dismiss(animated: true, completion: nil)
    }
    @IBAction func removeLastShot(_ sender: UIButton) {
        if i >= 1 {
            i -= 1
            switch shots[i] {
            case "X":
                runningScore -= 10
                runningX -= 1
            case "10":
                runningScore -= 10
            case "9":
                runningScore -= 9
            case "8":
                runningScore -= 8
            case "7":
                runningScore -= 7
            case "6":
                runningScore -= 6
            case "5":
                runningScore -= 5
            case "0":
                runningScore -= 0
            case "M":
                runningScore += 51
                runningX += 6
            default:
                return
            }
            
            shots[i] = "-"
            if runningScore > 0 && runningX >= 0 {
                runningTotal = "\(runningScore) - \(runningX) X"
            } else {
                runningTotal = "0 - 0X"
            }
            targetScore.text = runningTotal
            shotsListed = "\(shots[0]), \(shots[1]), \(shots[2]), \(shots[3]), \(shots[4]), "
            eachShot.text = shotsListed
        }
    }


}

将闭包传递给您的第二个视图控制器,并在第二个控制器的关闭完成时调用它,如果您愿意,甚至可以在此之前调用它:

class ScoringUI: UIViewController {

    var onDismissed: (() -> Void)? = nil       

    // ...

    @IBAction func back(_ sender: Any) {
        sendScoresToMain()
        self.dismiss(animated: true) { [weak self] in
             guard let self = self else { return }
             self.onDismissed?()
        }
    }

    // ...
}

class ViewController: UIViewController {
    // ...
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if(segue.identifier == "enterScoresSeg") {
            guard let entryVC = segue.destination as? ScoringUI else { return }
            entryVC.targetNumber = whatTargetIsThis
            entryVC.onDismissed = {
                // UPDATE UI HERE
            }
        }
    }

    // ...
}

顺便说一下,我不鼓励你使用全局变量,最好制作一个你可以在视图控制器之间传递的数据模型。通过这样做,您可以更改上面的代码以将该数据模型传递给 var onDismissed: ((_ newData: MyDataModel) -> Void)? = nil 并在另一端接收它并相应地更新您的 UI。