2

How can we animate a single character within a string? ie: I have the string: "Hey ". I would like to animate the emoji by setting it to rotate back and forth so it looks like it's waving.

To detect the emoji, I'm using:

extension String {
// Not needed anymore in swift 4.2 and later, using `.count` will give you the correct result
var glyphCount: Int {
    let richText = NSAttributedString(string: self)
    let line = CTLineCreateWithAttributedString(richText)
    return CTLineGetGlyphCount(line)
}

var isSingleEmoji: Bool {
    return glyphCount == 1 && containsEmoji
}

var containsEmoji: Bool {
    return unicodeScalars.contains { $0.isEmoji }
}

I'm using the emoji code here: Find out if Character in String is emoji?.

I'm unsure how to set up the animation

Ryan
  • 107
  • 7
  • 30

1 Answers1

2

I've very slightly modified this excellent answer by Rob in this post.

override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        animateEmojiBackandForth("")
    }

    func animateEmojiBackandForth (_ 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(rotationAngle: CGFloat( CGFloat.pi / 4))
                }, completion: { _ in
                    snapshotView.removeFromSuperview()
                })
        }
    }

You can modify the duration of the animation and the angle of the "wave" if you wish. I hope this was helpful!

Gif showing single animated character

Zaya
  • 508
  • 4
  • 8