Tuesday, 24 July 2018

How do I check if a generic view class actually implements init(frame:)?

Let's say I have a custom UIView subclass with a designated initializer:

class MyView: UIView {

    init(custom: String) {
        super.init(frame: .zero)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

As expected I cannot call MyView(frame: .zero) as it's not automatically inherited from UIView.

Then suppose I have a view builder class:

class Builder<V: UIView> {
    func build() -> V? {
        // Check if can call init(frame:) or not
        if V.instancesRespond(to: #selector(V.init(frame:))) {
            return V.init(frame: .zero) // <-- Crash here, because the check doesn't work
        } else { 
            return nil 
        }
    }
}

Here I checked first if the custom view V has init(frame:) or not, if yes, then call it.

However, it doesn't work, Builder<MyView>().build() will crash with:

Fatal error: Use of unimplemented initializer 'init(frame:)' for class '__lldb_expr_14.MyView'

V.instancesRespond(to: #selector(V.init(frame:))) always returns true, making this check useless. (Or did I use it incorrectly?)

Question: How do I check if generic view class V actually responds to init(frame:)?



from How do I check if a generic view class actually implements init(frame:)?

No comments:

Post a Comment