title: Swift 3 - Custom button (image and text) only draws correctly if there's no outlet?
body: <p><strong>EDIT: Although I accepted an answer that helped me get the buttons drawn correctly at runtime, I still have other issues. The root of which, I suspect, is the issue of <strike>why giving my custom button an outlet interferes with how it is drawn. I still need to know why this is.</strike> (see my answer below)</strong></p>
  
  <p>I have my own button class that extends UIButton (see below) and has several IBInspectable properties like border width/color, corner radius, and even start/end colors for a gradient background. I also use such properties for setting the image and titles' insets programmatically so I can account for various screen sizes.</p>
  
  <p>Previously I had an issue where if I changed the "View as" device in the storyboard, let's say from iPhone SE to iPhone 7, and then refreshed the views and ran on a physical iPhone SE it would deploy with the insets of an iPhone 7 instead of calculating the insets with the physical device's own screen size. However, I <em>nearly</em> resolved this problem by overriding <code>draw</code> in my custom button class.</p>
  
  <p>My problem now is that the overridden <code>draw</code> method is only called (or seems to be effective only when) <strong>the button has no outlet to the <code>ViewController</code> class it's placed in</strong>.</p>
  
  <p>For example:</p>
  
  <p><a href="https://i.stack.imgur.com/t1nHnl.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/t1nHnl.png" alt="enter image description here"></a></p>
  
  <p><sup>*The img is a placeholder; the insets suit the real imgs appropriately.</sup></p>
  
  <p>That bottom-right button has the gradient and corners drawn properly, where the other 3 do not. <em>I have confirmed that adding an outlet to this button makes it behave like the rest, and removing an outlet from any of the other 3 causes it to be drawn correctly</em>.</p>
  
  <p>For reference, the outlets are just</p>
  
  <pre><code>@IBOutlet weak var button1: UIButton!
  @IBOutlet weak var button2: UIButton!
  @IBOutlet weak var button3: UIButton!
  </code></pre>
  
  <p>immediately under the <code>class MyViewController: UIViewController {</code> declaration.</p>
  
  <p>Also, I didn't forget to set the Custom Class in the interface builder for each button.</p>
  
  <p><strong>Here is the button class:</strong></p>
  
  <pre><code>import UIKit
  
  @IBDesignable
  class ActionButton: UIButton {
  
      override init(frame: CGRect){
          super.init(frame: frame)
          setupView()
      }
      required init(coder aDecoder: NSCoder){
          super.init(coder: aDecoder)!
          setupView()
      }
  
      @IBInspectable var cornerRadius: CGFloat = 0{
          didSet{
              setupView()
          }
      }
      @IBInspectable var startColor: UIColor = UIColor.white{
          didSet{
              setupView()
          }
      }
      @IBInspectable var endColor: UIColor = UIColor.black{
          didSet{
              setupView()
          }
      }
      @IBInspectable var borderWidth: CGFloat = 0{
          didSet{
              self.layer.borderWidth = borderWidth
          }
      }
      @IBInspectable var borderColor: UIColor = UIColor.clear{
          didSet{
              self.layer.borderColor = borderColor.cgColor
          }
      }
  
      private func setupView(){
          let colors:Array = [startColor.cgColor, endColor.cgColor]
          gradientLayer.colors = colors
          gradientLayer.cornerRadius = cornerRadius
          gradientLayer.endPoint = CGPoint(x: 0.5, y: 1.0)
          self.setNeedsDisplay()
      }
  
      var gradientLayer: CAGradientLayer{
          return layer as! CAGradientLayer
      }
  
      override func draw(_ rect: CGRect) {
  
          //Draw image
  
          setupView()
  
          let btnW = self.frame.size.width
          let btnH = self.frame.size.height
  
          //Compute and set image insets
          let topBtnInset = btnH * (-5/81)
          let bottomBtnInset = -4 * topBtnInset
          let leftBtnInset = btnW / 4 //btnW * (35/141)
          let rightBtnInset = leftBtnInset
  
          self.imageEdgeInsets = UIEdgeInsets(top: topBtnInset, left: leftBtnInset, bottom: bottomBtnInset, right: rightBtnInset)
  
          //Compute and set title insets
          let topTitleInset = btnH * (47/81)
          let bottomTitleInset = CGFloat(0)
          let leftTitleInset = CGFloat(-256) //Image width
          let rightTitleInset = CGFloat(0)
  
          self.titleEdgeInsets = UIEdgeInsets(top: topTitleInset, left: leftTitleInset, bottom: bottomTitleInset, right: rightTitleInset)
  
          //Draw text
  
          //Default font size
          self.titleLabel?.font = UIFont.boldSystemFont(ofSize: 15)
  
          if(btnH &gt; 81){
              self.titleLabel?.font = UIFont.boldSystemFont(ofSize: 17)
          }else if(btnH &gt; 97){
              self.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
          }
  
      }
  
      override class var layerClass: AnyClass{
          return CAGradientLayer.self
      }
  
  }
  </code></pre>
  
  <p><sup>Please ignore the wonky way I handled insets, font sizes, etc..</sup> </p>
  
  <p>Does anyone know why specifying an outlet for the button makes it not draw the layer correctly?</p>