Get the concrete class calling the extension

(I tagged it with generics because first I was playing with various solutions that used generics..)

Hello! I would like to understand if there's an easier way to accomplish what I want then the solution I found.

I want a function available on instances of UIView and possible subclasses. My direct approach was:

extension UIView {
    func myFunc(_ arg: @escaping ((Self) -> Void)) {
        print(arg)
    }
}

However then I get: Value of type 'Self' has no member 'text'

UILabel().myFunc { label in
    label.text = ""
}

I had to go via associated value like this:

protocol X {
    associatedtype View: UIView
    var __view: View { get }
}

extension UIView: X {
    typealias View = UIView
    var __view: UIView { self }
}

extension X {
    func myFunc(_ arg: @escaping ((Self) -> Void)) {
        print(arg)
    }
}

// Now this compiles

UILabel().myFunc { label in
    label.text = ""
}

Can someone ELI5 why I can't do the first approach and is there a "better" solution the one I Found?

Can you provide a more realistic use case that explains what you're trying to achieve? It's hard for me to understand the purpose of a function that merely prints the value passed in to it.

A concrete example would be to animate something (which requires it to be UIView) and then change the content based on the specific concrete type, such as text or image:

extension X {
    func myFunc(_ arg: @escaping ((Self) -> Void)) {
        UIView.animate(withDuration: 0.2, animations: {
            __view.alpha = 0.0
        }, completion: { _ in
            arg(self)
            UIView.animate(withDuration: 0.2, animations: {
                __view.alpha = 1.0
            }, completion: nil)
        })
    }
}