title: How do I check if a generic view class actually implements init(frame:)?
body: <p>Let's say I have a custom UIView subclass with a designated initializer:</p>
  
  <pre class="lang-swift prettyprint-override"><code>class MyView: UIView {
  
      init(custom: String) {
          super.init(frame: .zero)
      }
  
      required init?(coder aDecoder: NSCoder) {
          super.init(coder: aDecoder)
      }
  }
  </code></pre>
  
  <p>As expected I <em>cannot</em> call <code>MyView(frame: .zero)</code> as it's not <a href="https://docs.swift.org/swift-book/LanguageGuide/Initialization.html#ID222" rel="noreferrer">automatically inherited</a> from <code>UIView</code>.</p>
  
  <p>Then suppose I have a view builder class:
  </p>
  
  <pre><code>class Builder&lt;V: UIView&gt; {
      func build() -&gt; V? {
          // Check if can call init(frame:) or not
          if V.instancesRespond(to: #selector(V.init(frame:))) {
              return V.init(frame: .zero) // &lt;-- Crash here, because the check doesn't work
          } else { 
              return nil 
          }
      }
  }
  </code></pre>
  
  <p>Here I checked first if the custom view <code>V</code> has <code>init(frame:)</code> or not, if yes, then call it.</p>
  
  <p>However, it doesn't work, <code>Builder&lt;MyView&gt;().build()</code> will crash with:</p>
  
  <blockquote>
    <p>Fatal error: Use of unimplemented initializer 'init(frame:)' for class '__lldb_expr_14.MyView'</p>
  </blockquote>
  
  <p><code>V.instancesRespond(to: #selector(V.init(frame:)))</code> always returns <code>true</code>, making this check useless. (Or did I use it incorrectly?)</p>
  
  <p><strong>Question: How do I check if generic view class <code>V</code> actually responds to <code>init(frame:)</code>?</strong></p>
  
  <hr>
  
  <p><strong>Updated 1:</strong>
  I also tried <code>V.responds(to: #selector(V.init(frame:)))</code> as @kamaldeep and @Pranav have pointed out. However, it always returns <code>false</code> no matter I override init(frame:) on <code>MyView</code> or not.</p>
  
  <p><strong>Updated 2: What I'm trying to do:</strong></p>
  
  <p>To be more clear, I'm building a <a href="https://github.com/aunnnn/ViewElements" rel="noreferrer">framework</a> that automatically initializes <code>UIView</code> from this enum:</p>
  
  
  
  <pre><code>enum ViewBuildMethod {
      case nib
      case nibName(String)
      case frame(CGRect)
      case custom(() -&gt; UIView)
  }
  </code></pre>
  
  <p>and that view to be used with the framework must adopt this protocol and specify how to build:</p>
  
  
  
  <pre><code>protocol SomeViewProtocol where Self: UIView {
  
      // ... other funcs
  
      static func buildMethod() -&gt; ViewBuildMethod
  }
  </code></pre>
  
  <p>The issue is that I want the <code>override init(frame:)</code> to be <strong>optional</strong> and allows a custom designated initializer (like in <code>MyView</code>). Then, emit <code>fatalError</code> with an error message when the <code>init(frame:)</code> is used (indirectly) on a view that hasn't overridden it yet. This indicates an illegal use of the framework (e.g., <code>MyView</code>'s <code>buildMethod</code> returns <code>.frame(.zero)</code>), that can't be checked in compile time:</p>
  
  <pre class="lang-swift prettyprint-override"><code>class MyView: UIView, SomeViewProtocol {
  
      init(custom: String) {
          super.init(frame: .zero)
      }
  
      required init?(coder aDecoder: NSCoder) {
          super.init(coder: aDecoder)
      }
  
      // ILLEGAL!!
      static func buildMethod() -&gt; ViewBulidMethod {
          return .frame(.zero) // &lt;-- Illegal, the framework will call V.init(frame: .zero) eventually
      }
  
      // LEGAL
      // static func buildMethod() -&gt; ViewBuildMethod {
      //     return .custom({ () -&gt; UIView in
      //         return MyView(custom: "hello")
      //     })
      // }
  }
  </code></pre>
  
  <p>The error message could be sth like <code>V.init(frame:) is called indirectly but V doesn't override this designated initializer. Please override init(frame:) to fix this issue</code>. 
  I can let it crash like above, but it will be more clear if I can add some meaningful message before that happens.</p>