Sure, you do need to use the "weak self" concept there.
In fact note: it is indeed very common in that situation that a VC is trashed during an animation ... so indeed, it's one of the places you "most need" to use the weak-self idea. It's a very common mistake in projects to forget that in an animation.
By the way, here's a handy syntax any time you need weak self:
func animate() {
UIView.animate(withDuration: 0.3, animations: { [weak self] in
guard let self = self else { return print("gotchya!") }
self.label.alpha = 0.5
}) { [weak self] in
guard let self = self else { return print("gotchya!") }
self.animate()
}
}
Adding this line ..
guard let self = self else { return }
.. can seem a bit long-winded, but, it means you then don't need the "?"
after "self" every time you use it in long blocks.
Often you will have many uses of "self ..." inside such a block, and it seems more consistent to just use the "let self = self" idiom.

So even if there is only one line of code in the block (as in your two examples) it's a good way to be absolutely consistent everywhere and keep things simple.
Note that whenever you have a { return }
you can just add a print statement so that you know what is going on during development ..
.... { [weak self] in
guard let self = self else { return print("I avoided a crash, woot!") }
or
.... { [weak self] in
guard let self = self else { return print("logical disaster near line 66") }
You do not have to do that, "{ return }" is fine. It's just for your convenience.
What the hell is this "self = self" business?
If you find the "self = self" idiom confusing ....... honestly, just don't worry about it. Always use that idiom. It's really just the "standard" thing you will see everywhere.
Always go for simple consistency in your code base!
More weak self mysteries ...
Here's a interesting QA from a handsome list member: Where does the weak self go?
And later there's this sort of confusion to worry about: What is the difference between a weak reference and an unowned reference?