在呈现的 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。
我有一个 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。