#ios #swift #uiviewcontroller
#iOS #swift #uiviewcontroller
Вопрос:
У меня есть mainVC, который используется для выбора элемента для редактирования, он состоит из четырех кнопок и четырех меток. Когда вы выбираете кнопку, она передает и идентификатор кнопки (через prepare) и выполняет переход (присутствует модально). После того, как пользователь вводит данные, нажимает кнопку «Сохранить», он применяет данные к глобальной переменной и вызывает 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 amp;amp; 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 amp;amp; 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 amp;amp; 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
}
}
}
Комментарии:
1. Добро пожаловать в SO, пожалуйста, добавьте свой код, чтобы помочь нам лучше отлаживать
2. Спасибо, добавлен код.
3. Как вы можете получить доступ
ViewController.GlobalVars
? В вашем ViewController вы не объявили его какstatic
,ViewController.GlobalVars
должно было выдать ошибку компиляции
Ответ №1:
Передайте закрытие вашему второму контроллеру представления и вызовите его, когда завершится удаление второго контроллера или даже раньше, если хотите:
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
и получить ее на другом конце, а также соответствующим образом обновить свой пользовательский интерфейс.
Комментарии:
1. Большое вам спасибо! Теперь, когда у меня есть способ передать данные обратно, я избавлюсь от глобальных переменных. Приветствия!!!