UIView.animate, кажется, замораживает другие обновления просмотра - PullRequest
0 голосов
/ 23 сентября 2019

У меня есть UIView, который является часами обратного отсчета, которые я анимирую с помощью UIView.animate.Существует также запущенный таймер, который показывает время на UILabel, когда таймер срабатывает.Когда игра находится в переходе (во время обратного отсчета), UILabel перестает меняться.Я поместил оператор «print» в функцию таймера, и он появился, как и ожидалось.

Я искал подсказки о том, что, возможно, UIVIew.animate блокирует другие представления, но я вижу, как несколько приложений перемещают представления одновременно.Может быть, я должен положить вещи в другую ветку?

@objc func timerUpdate () {
        if gameIsRunning {
            let endTime = Date.init()
            let difference = endTime.timeIntervalSince(gameClock)
            let formattedString = String(format: "%3.1f",kDefaultGameClock - difference)
            timerLabel.text = "\(formattedString)"
        }
}


private func countDownFrom (x: Int) {
    if x != 0 && x > 0 {
        UIView.animate(withDuration: 1.0,
                       delay: 0.0,
                       usingSpringWithDamping: 0.5,
                       initialSpringVelocity:1.0,
                       options: .curveEaseOut,
                       animations: {
                        self.successLabel.text = "\(x)"
                        self.successLabel.transform = self.successLabel.transform.scaledBy(x: 4.0, y: 4.0)

        }, completion: {_ in
            self.successLabel.transform = self.successLabel.transform.scaledBy(x: 0.250, y: 0.250)
            if (x - 1 > 0) {
                self.countDownFrom(x: x - 1)
            } else {
                self.successLabel.text = kDefaultGoodGame
                self.successLabel.isHidden = true
                self.startTheGame()
                self.updateScreen()
            }
        })
    }
}

1 Ответ

1 голос
/ 23 сентября 2019

Когда я попробовал ваш код в пустом проекте, я смог обновить обе метки.

Если timerLabel не обновляется, это может быть проблемой с потоком.Обновления пользовательского интерфейса должны быть в основном потоке.

DispatchQueue.main.async {
    self.timerLabel.text = "\(formattedString)"
}

Для чего это стоит, вот что я работаю в пустом проекте.

@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var successLabel: UILabel!

let kDefaultGameClock = 30.0
var gameIsRunning = false
var gameClock = Date()

override func viewDidLoad() {
    super.viewDidLoad()
    start()
}

func start() {
    gameIsRunning = true
    countDownFrom(x: 30)
    Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(timerUpdate), userInfo: nil, repeats: true)
}

@objc func timerUpdate() {
    if gameIsRunning {
        let endTime = Date.init()
        let difference = endTime.timeIntervalSince(gameClock)
        let formattedString = String(format: "%3.1f", kDefaultGameClock - difference)
        timerLabel.text = "\(formattedString)" // Could be a main thread issue here?
    }
}

private func countDownFrom(x: Int) {
    if x != 0 && x > 0 {
        UIView.animate(withDuration: 1.0,
                       delay: 0.0,
                       usingSpringWithDamping: 0.5,
                       initialSpringVelocity:1.0,
                       options: .curveEaseOut,
                       animations: {
                        self.successLabel.text = "\(x)"
                        self.successLabel.transform = self.successLabel.transform.scaledBy(x: 4.0, y: 4.0)

        }, completion: {_ in
            self.successLabel.transform = self.successLabel.transform.scaledBy(x: 0.250, y: 0.250)
            if (x - 1 > 0) {
                self.countDownFrom(x: x - 1)
            } else {
                self.successLabel.text = ""
                self.successLabel.isHidden = true
                //self.startTheGame()
                //self.updateScreen()
            }
        })
    }
}

Немного не по теме, но выВозможно, вы захотите объявить ваш таймер как переменную, чтобы сделать его недействительным, как только вы закончите обновление timerLabel.

...