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.
transitionWithViewinstead ofanimateWithDurationand no extra view is needed.transitionWithViewworks for the color. I put that in the example because I couldn't figure out how to scale the size of a character in the string - so i put the closest example i could think of which was the color. Could you suggest how I'd go about making the letters "pop" (scale up and back down) as well?CGRectfor the relevant parts to be animated, taking snapshot of before and after appearance, animating the transition of snapshots, etc. You certainly can do it, but you should ask yourself how much work you want to engage in for a simple effect.