title: reusable view controller with view In storyboard (multiple in one scene)
body: <p>I'm building a little math game app for two players, for my daughter and friends (but I'm planing to also allow singleplayer later on). For now it's for 2 players and both sit on opposite sides of the iPhone.
  Each player has the same buttons, same questions to answer. They push a button (of a self build numpad), the vc gets the touch event, it verifies the answer and based on the result a scoreView gets animated and scoreCounters are updated.</p>
  <p>The game logic for a side is kind of done. And now I'd like to reuse that logic for one view, and use it twice (same numpad and textfields but on opposite side)
  But I can't find a away to have such a reusable view with a vc working. I thought I could build the view in a xib connect everything to it's view controller and then reuse that view/vc couple in my storyboard the way I want. But it fails.</p>
  <p>I have the following setup at the moment (note: I'm using basic views here and vcs like in <a href="https://medium.com/flawless-app-stories/how-to-reuse-complex-xib-designed-views-in-storyboards-using-modern-swift-generics-property-e0b7c06b07a6" rel="nofollow noreferrer">this tutorial</a> for now, it's for testing, if all works I will replace the view and vc with the real, bit more complex logic/views):</p>
  <p>The relevant files in my &quot;test&quot; setup:</p>
  <ul>
  <li>MessageView.xib</li>
  <li>MessageView.swift</li>
  <li>MessageViewController.swift</li>
  <li>RootController.swift</li>
  <li>Main.storyboard</li>
  </ul>
  <p>The MessageView.xib has just one label connected as an outlet in the MessageView class, but I'd love to have outlets to labels and buttons in my view controller.
  The MessageViewController has an outlet to messageView (I'd prefer outlets to views and actions and have the view be the direct view controllers view and have the vc handle all the actions and logic).</p>
  <p>In my storyboard I have my RootViewController (will be gameFieldViewController).
  The RootViewController has a stackView with two containers.
  Each container VC is of type MessageViewController (will be the calcViewController).
  The view of that container VC has a subview of type MessageViewWrapper (will be calcView).</p>
  <p>My problem now is that in the messageView xib I would like to connect all actions (there's only a label in that example, but it will be my calculator pad with buttons) to my MessageViewController. So that the vc can handle all the logic. But I can only connect the MessageView to the MessageViewController and so I would need to catch all actions in the view and then delegate everything to the MessageViewController I guess, which I'd do if there's no other way, but I still got hope that I just know swift+xcode to little.</p>
  <p>I would prefer to have a MessageViewController.xib that does everything like normally build in main.storyboard and then I would like to be able to reuse that controller as often as I want, like in the stackView with multiple containers, each having it's own instance of that vc but it seems to me like as if I could only reuse views, not viewcontroller+view couples.</p>
  <h2>Question:
  <strong>Is that possible ? How ? How to setup ?</strong></h2>
  <p>I tried to set the files owner of the MessageView.xib to be MessageViewController as well as the class of the container view in the Main.storyboard to be MessageViewController to then connect the label directly to the ViewController and modify the text from within the VC but it fails, which I guess is no surprise, but it was the only thing I could think of.</p>
  <p>Here's some code:</p>
  <pre><code>// MessageView.swift
  import UIKit
  
  @IBDesignable class MessageViewWrapper : NibWrapperView&lt;MessageView&gt; { }
  // wrapper thingy found here 
  //https://medium.com/flawless-app-stories/how-to-reuse-complex-xib-designed-views-in-storyboards-using-modern-swift-generics-property-e0b7c06b07a6
  class MessageView: UIView {
      
      @IBOutlet weak var messageLabel: UILabel!
      
      var message : String = &quot;&quot; {
          didSet { messageLabel.text = message }
      }
  }
  
  // MessageViewController.swift
  import UIKit
  
  class MessageViewController: UIViewController {
      @IBOutlet weak var messageView: UIView!
      @IBOutlet weak var messageLabel: UILabel!
      
      override func viewDidLoad() {
          (messageView as? MessageViewWrapper)?.contentView.message = &quot;Yeepee !!!&quot;
      }
      
      func inHere() {
          messageLabel.text = &quot;AHA&quot;
      }
  }
  
  // RootViewController
  import SwiftUI
  class RootViewController: UIViewController {
      var vcTop: MessageViewController!
  
      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
          if (segue.identifier == &quot;topViewSegue&quot;) {
              let vc = segue.destination
              guard let vcTop = vc as? MessageViewController else {return}
              
              vcTop.inHere() // fails
          }
      }
  }
  
  // NibWrapperView.swift
  import UIKit
  
  /// Class used to wrap a view automatically loaded form a nib file
  class NibWrapperView&lt;T: UIView&gt;: UIView {
      /// The view loaded from the nib
      var contentView: T
  
      required init?(coder: NSCoder) {
          contentView = T.loadFromNib()
          super.init(coder: coder)
          prepareContentView()
      }
      
      override init(frame: CGRect) {
          contentView = T.loadFromNib()
          super.init(frame: frame)
          prepareContentView()
      }
      
      private func prepareContentView() {
          contentView.translatesAutoresizingMaskIntoConstraints = false
          addSubview(contentView)
  
          contentView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
          contentView.topAnchor.constraint(equalTo: topAnchor).isActive = true
          contentView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
          contentView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
      }
      
      override func prepareForInterfaceBuilder() {
          super.prepareForInterfaceBuilder()
          contentView.prepareForInterfaceBuilder()
      }
  }
  
  extension UIView{
      static func loadFromNib() -&gt; Self {
          let bundle = Bundle(for: self)
          let nib = UINib(nibName: String(describing: self), bundle: bundle)
          return nib.instantiate(withOwner: nil, options: nil).first as! Self
      }
  }
  </code></pre>
  <p>MessageView.xib</p>
  <p><a href="https://i.stack.imgur.com/pQsAB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/pQsAB.png" alt="MessageView.xib" /></a></p>
  <p>Main.storyboard
  <a href="https://i.stack.imgur.com/4bvg2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4bvg2.png" alt="Main.storyboard" /></a></p>
  <p><strong>Note:</strong>
  Please write a comment if something is off with my question. As you know I have kids, so sometimes I write my text to short or it's nonsense as I often have my children next to me, which often is kind of distracting :D</p>