asyncAfter не откладывает первое выполнение на указанное время - PullRequest
0 голосов
/ 31 декабря 2018

Я пытаюсь анимировать текстовое представление, чтобы символы строки появлялись один за другим, а затем исчезали один за другим, начиная с первого символа после 0,5-секундной задержки.

Я близок, единственная проблема, которую я имею, заключается в том, что самый первый персонаж удаляется сразу же, как если бы он никогда не появлялся.Любые идеи, вот моя функция:

extension UITextView {

    func animate(newText: String) {

        DispatchQueue.main.async {

            self.text = ""

            for (index, character) in newText.enumerated() {
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1 * Double(index)) {
                    self.text?.append(character)
                }

                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5 * Double(index)) {
                    self.text?.remove(at: newText.startIndex)
                }
            }
        }
    }
}

1 Ответ

0 голосов
/ 31 декабря 2018

Проблема в том, что первый символ имеет индекс 0, поэтому задержка равна .now() + 0.5 * 0, что упрощается до .now().

Добавьте к задержке константу:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5 * Double(index) + 0.5) {
                                                                    ^^^^^^

Это заставит первый символ исчезнуть через 1 секунду.

В качестве альтернативы:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5 * Double(index + 1)) {

Кроме того, использование Timer здесь может быть более подходящим, если вашТекст длинный, как сказал Роб в комментариях.

var index = 0
let characterArray = Array(newText)

Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { (timer) in
    textView.text! += "\(characterArray[index])"
    index += 1
    if index == characterArray.endIndex {
        timer.invalidate()
    }
}
...