在Swift中动画字符串淡入/淡出 [英] Animating strings fading in/out in Swift

查看:410
本文介绍了在Swift中动画字符串淡入/淡出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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

  UIView.animateWithDuration(1,delay:0.5,options:.CurveEaseOut ,动画:{
self.stringForPlayer.addAttribute(
NSForegroundColorAttributeName,
值:UIColor.greenColor(),
范围:NSRange(位置:self.rangeOfText,长度:1) )
self.textViewForPlayer.attributedText = self.textForPlayer
},完成:{已在
println( FINISHED)}中完成

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

解决方案

您可以使用



如果仅将文本的颜色作为动画,则可能需要先将其淡化为 clear ,然后再将其淡化为所需的颜色颜色(使它弹出更多),您可以使用完成块:

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

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

UIView.transition(with:textView,duration:0.25,options:.transitionCrossDissolve,animations:{
self.textView.attributedText =字符串
},完成:{_在
中string.addAttribute(.foregroundColor,值:UIColor.red,范围:范围)
UIView.transition (with:self.textView,持续时间:0.25,选项:.transitionCrossDissolve,动画:{
self.textView.attributedText =字符串
})
})
}

结果:





有关Swift的早期版本,请参见此答案的先前版本


I'm new to programming - but I've made strides learning Swift for iOS in the last two months. I'm making a simple typing game - and the way I've structured my project is that I have a hidden UITextView that detects the character pressed by the player, and I match that character string with a visible UITextView's character string.

What I'm looking to do now is to add some sort of animation - I'd like the individual letters to fade in/out

I've created an attributed string, added it to a UITextView, and I just can't figure out a way to animate a specific range in the string. I've tried using something along the lines of this:

            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")}
            )

with no luck. I figure maybe UIView animations are only on the view object itself and can't be used on the attributed string. Any ideas or even workarounds to make this happen? Any help is appreciated, thanks a lot!

解决方案

You can use transition(with:...) to do an animation. In this case, fading the word ipsum into green. E.g. in Swift 3 and later:

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
})

Originally, you also asked about having the text grow and shrink during this animation and that’s more complicated. But you can search for the text, find the selectionRects, take snapshots of these views, and animate their transform. For example:

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()
            })
    }
}

And

growAndShrink("consectetaur cillium")

Will result in:

If you are animating just the color of the text, you may want to fade it to clear before fading it to the desired color (making it "pop" a little more), you could use the completion block:

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
        })
    })
}

Resulting in:

For previous versions of Swift, see prior revision of this answer.

这篇关于在Swift中动画字符串淡入/淡出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆