在Swift中动画字符串淡入/淡出

Chr*_*ris 3 string animation ios swift

我是编程新手,但是在过去两个月中,我在学习iOS的Swift方面取得了长足的进步。我正在做一个简单的打字游戏-我构造项目的方式是,我有一个隐藏的UITextView,可以检测玩家按下的字符,并将该字符串与可见的UITextView字符串匹配。

我现在想要做的是添加某种动画-我希望各个字母淡入/淡出

我已经创建了一个属性字符串,并将其添加到UITextView中,但我只是想不出一种方法来对字符串中的特定范围进行动画处理。我已经尝试使用一些类似的方法:

            UIView.animateWithDuration(1, delay: 0.5, options: .CurveEaseOut, animations: {
                self.stringForPlayer.addAttribute(
                    NSForegroundColorAttributeName,
                    value: UIColor.greenColor(),
                    range: NSRange(location: self.rangeOfText, length: 1))
                self.textViewForPlayer.attributedText = self.textForPlayer
                }, completion: { finished in
                    println("FINISHED")}
            )
Run Code Online (Sandbox Code Playgroud)

没有运气。我认为也许UIView动画仅在视图对象本身上,而不能在属性字符串上使用。有什么想法甚至解决方法可以做到这一点?任何帮助表示赞赏,非常感谢!

Rob*_*Rob 5

您可以用来transition(with:...)制作动画。在这种情况下,将单词淡入ipsum绿色。例如,在Swift 3及更高版本中:

let range = (textView.text as NSString).range(of: "ipsum")
if range.location == NSNotFound { return }

let string = textView.attributedText.mutableCopy() as! NSMutableAttributedString
string.addAttribute(.foregroundColor, value: UIColor.green, range: range)

UIView.transition(with: textView, duration: 1.0, options: .transitionCrossDissolve, animations: {
    self.textView.attributedText = string
})
Run Code Online (Sandbox Code Playgroud)

最初,您还问过有关在此动画中使文本增长和缩小的问题,这更加复杂。但是您可以搜索文本,查找selectionRects,为这些视图拍摄快照并为其设置动画transform。例如:

func growAndShrink(_ searchText: String) {
    let beginning = textView.beginningOfDocument

    guard let string = textView.text,
        let range = string.range(of: searchText),
        let start = textView.position(from: beginning, offset: string.distance(from: string.startIndex, to: range.lowerBound)),
        let end = textView.position(from: beginning, offset: string.distance(from: string.startIndex, to: range.upperBound)),
        let textRange = textView.textRange(from: start, to: end)
            else { return }

    textView.selectionRects(for: textRange)
        .forEach { selectionRect in
            guard let snapshotView = textView.resizableSnapshotView(from: selectionRect.rect, afterScreenUpdates: false, withCapInsets: .zero) else { return }
            snapshotView.frame = view.convert(selectionRect.rect, from: textView)
            view.addSubview(snapshotView)
            UIView.animate(withDuration: 1, delay: 0, options: .autoreverse, animations: {
                snapshotView.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
            }, completion: { _ in
                snapshotView.removeFromSuperview()
            })
    }
}
Run Code Online (Sandbox Code Playgroud)

和

growAndShrink("consectetaur cillium”)
Run Code Online (Sandbox Code Playgroud)

将导致:

增长

如果仅对文本的颜色进行动画处理,则可能需要clear先将其淡入淡出,然后再将其淡化为所需的颜色(使它“弹出”更多),可以使用该completion块:

func animateColor(of searchText: String) {
    let range = (textView.text as NSString).range(of: searchText)
    if range.location == NSNotFound { return }

    let string = textView.attributedText.mutableCopy() as! NSMutableAttributedString
    string.addAttribute(.foregroundColor, value: UIColor.clear, range: range)

    UIView.transition(with: textView, duration: 0.25, options: .transitionCrossDissolve, animations: {
        self.textView.attributedText = string
    }, completion: { _ in
        string.addAttribute(.foregroundColor, value: UIColor.red, range: range)
        UIView.transition(with: self.textView, duration: 0.25, options: .transitionCrossDissolve, animations: {
            self.textView.attributedText = string
        })
    })
}
Run Code Online (Sandbox Code Playgroud)

导致:

红色

对于Swift的早期版本,请参见此答案的先前版本。