title: Swift: Converting UIButton into UIBarButtonItem, does it really have to be this complicated?
body: <p>I have written an extension on <code>UIButton</code> which converts a <code>UIButton</code> into a <code>UIBarButtonItem</code>.</p>
  
  <p>I tried to most simple solution using <code>init(customView</code> on <code>UIBarButtonItem</code> passing in my button, like this:</p>
  
  <pre><code>lazy var myButton: UIButton = { 
      let button = UIButton(type: .custom)
      // setting up button here...
      return button
  }()
  
  let barButtonItem = UIBarButtonItem(customView: myButton)
  </code></pre>
  
  <p>But I had several constraints issues. Actually I did not only want to put one button, but three items in the navigation bar. So I tried putting my three buttons into a <code>UIStackView</code> and then set <code>navigationItem.rightBarButtonItem = UIBarButtonItem(customView: stackView)</code> which works like a charm <strong>on iOS 10</strong>. But on <strong>iOS 9</strong> the position of the buttons did not work.</p>
  
  <p>Anyway I resorted to using <code>UIBarButtonItem</code> instead of <code>UIButton</code>s, but I did not want to create <code>UIBarButton</code>s for iOS 9 but <code>UIButton</code>s for iOS 10. So I wrote an extension creating <code>UIBarButtonItem</code>s from <code>UIButton</code>s. Which enabled this code.</p>
  
  <h2>Solution handling iOS 9 and iOS 10</h2>
  
  <pre><code>func setupNavigationBar() {
      if #available(iOS 10.0, *) {
          let stackView: UIStackView = [.views(buttons)] //syntax enabled by framework `ViewComposer`: github.com/Sajjon/ViewComposer
          navigationItem.rightBarButtonItem = UIBarButtonItem(customView: stackView)
      } else {
          navigationItem.rightBarButtonItems = buttons.reversed().flatMap { $0.barButtonItem } // syntax enabled by extension below
      }
  }
  </code></pre>
  
  <p>Here is my code for my extension.</p>
  
  <h2>Extension UIButton</h2>
  
  <pre><code>extension UIButton {
  
      var barButtonItem: UIBarButtonItem? {
          return barButtonItem()
      }
  
      func barButtonItem(
          style: UIBarButtonItemStyle = .plain,
          state: UIControlState = .normal,
          controlEvent: UIControlEvents = .primaryActionTriggered
          ) -&gt; UIBarButtonItem? {
  
          guard
              let target = allTargets.first,
              let selectorName = actions(forTarget: target, forControlEvent: controlEvent)?.first,
              case let image = image(for: state), case let title = title(for: state),
              (image != nil || title != nil)
              else { return nil }
  
          let action = NSSelectorFromString(selectorName)
  
          if let image = image {
              return UIBarButtonItem(image: image, style: style, target: target, action: action)
          }
  
          if let title = title {
              return UIBarButtonItem(title: title, style: style, target: target, action: action)
          }
  
          return nil //should not happen
      }
  }
  </code></pre>
  
  <h3>Question 1: Why did positioning the UIButtons inside the UIStackView not work on iOS 9?</h3>
  
  <h3>Question 2: Is my extension unnecessarily complex? Or insecure somehow?</h3>