ios - 当点击手势执行时,带有 uitextfield 的逐字母动画同时执行

标签 ios swift animation uitextview

Stack Overflow 新手,Swift 相对新手。我试图在点击屏幕时执行一个字母一个字母的动画,但是当多次点击屏幕时,字母会出现困惑。

我很确定这可能是因为下一行文本正在动画化,当前行文本正在动画化,但我不确定如何确保当前行是动画化的在下一个之前完成动画。执行此操作的正确方法是什么?

   @objc func handleTap(sender: UITapGestureRecognizer? = nil) {



    if counter < textArray.count {
        storyTextView.text = textArray[counter] //
        storyTextView.animate(newText: storyTextView.text ?? textArray[counter], characterDelay: 0.1)
    counter += 1


    }
}

extension UITextView {

    func animate(newText: String, characterDelay: TimeInterval) {

    DispatchQueue.main.sync {

        self.text = ""

        for (index, character) in newText.characters.enumerated() {

            DispatchQueue.main.asyncAfter(deadline: .now() + characterDelay * Double(index)) {
                self.text?.append(character) // animation function is running at same time

                print("characterDelay \(characterDelay) index \(index)")
            }
        }
    }
}

最佳答案

似乎当用户第二次点击时基本上两个动画开始同时发生。由于您使用 2 个不同的文本作为源并逐个字符附加来创建一个新字符串,因此您可能会从中得到交错的字符串。

您没有指定用户第二次点击时实际想要的结果是什么。最简单的方法是简单地结束当前动画并填充整个当前字符串。最困难的是同时为两者制作动画,我现在甚至不想深入思考。

我相信在你的情况下使用计时器比调度更好。您可以创建类似的内容:

let timer = Timer.scheduledTimer(withTimeInterval: characterDelay, repeats: true, block: {{ _ in
     // Append the character here
}})

最好通过执行以下操作来耗尽字符串而不是索引:

let newText = oldText + String(textToAppend.remove(at: textToAppend.startIndex))

因此这将从源字符串中删除第一个字符,同时将其附加到目标字符串。

现在将它们放在一起,我将执行以下操作:

protocol StringAnimatorDelegate: class {
    func stringAnimator(_ sender: StringAnimator, didUpdateStringTo string: String)
    func stringAnimator(_ sender: StringAnimator, didFinishWithString string: String)
}

class StringAnimator {

    var delegate: StringAnimatorDelegate?

    private(set) var text: String = ""
    private var timerWithString: (timer: Timer, stringToAppend: String)?

    func animateText(_ stringToAppend: String, intervalDuration: TimeInterval) {
        if let timerWithString = timerWithString {
            self.timerWithString = nil
            // We have a string already to append. Finish it
            timerWithString.timer.invalidate() // Stop the previous timer
            self.text = self.text + timerWithString.stringToAppend // Append whatever is left to append
            self.delegate?.stringAnimator(self, didFinishWithString: self.text)
        }

        // Create a new timer
        let timer = Timer.scheduledTimer(withTimeInterval: intervalDuration, repeats: true) { timer in
            guard let string = self.timerWithString?.stringToAppend, string.count > 0 else {
                // String is either nil or depleted. Finish timer.
                self.timerWithString?.timer.invalidate()
                self.timerWithString = nil
                self.delegate?.stringAnimator(self, didFinishWithString: self.text)
                return
            }
            var depletingString = string // Make a mutable copy of string to deplete so we may modify it
            self.text = self.text + String(depletingString.remove(at: depletingString.startIndex)) // Modify both strings
            self.timerWithString = (timer, depletingString) // Assign new values
            self.delegate?.stringAnimator(self, didUpdateStringTo: self.text)
        }
        self.timerWithString = (timer, stringToAppend)
    }

}

现在这是一个用于对字符串进行动画处理的完整系统。您可以创建一个实例,例如:

let animator = StringAnimator()
animator.delegate = self

然后,例如,在点击时,您只需像现在一样调用 animator.animateText(... )。并且您扩展您的类以支持动画师的委托(delegate),并且在这两种方法上只需更新您的文本字段或您正在使用的任何文本容器。或者您可以简单地将这段代码放入您的类中并直接使用它,就像您到目前为止一直在做的那样。

关于ios - 当点击手势执行时,带有 uitextfield 的逐字母动画同时执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52070108/

相关文章:

ios - 如何自定义WebRTC视频源?

ios - (ios-charts)在不使用 Storyboard的情况下无法在 UICollectionView 中显示折线图

swift - 无法读取属性 'keyCode' 'character' 检测修改键+数字键时断言失败

html - 如何为横幅图像创建 tween-lite spark 动画?

javascript - ReactCSSTransitionGroup 动画不流畅

ios - 应用程序崩溃 - 从应用程序商店安装但不是在本地安装时

ios - Swift 将 AnyObserver 绑定(bind)到 Observable

javascript - 为什么这个圆没有围绕正确的中心旋转?

objective-c - UILocalizedIndexedCollat​​ion 不显示中文字符

ios - 代码签名 "libswiftAVFoundation.dylib"失败