I have an app that uses custom buttons, the buttons should simply have a background image. Instead of adding the background image to all buttons, I'd rather have a UIButton subclass. It would be great if the custom button also rendered properly in Interface Builder. This is my attempt so far:
import UIKit
@IBDesignable
class STACPatientButton: UIButton {
override init(frame: CGRect) {
NSLog("initWithFrame");
super.init(frame: frame)
_setup()
}
required init(coder: NSCoder) {
NSLog("initWithCoder");
super.init(coder: coder)
_setup()
}
override func prepareForInterfaceBuilder() {
_setup()
}
private func _setup() {
if let image = UIImage(named:"patientButton.png") {
let insets = UIEdgeInsetsMake(8.0, 8.0, 8.0, 8.0)
let strechableImage = image.resizableImageWithCapInsets(insets)
self.setBackgroundImage(strechableImage, forState: UIControlState.Normal)
self.contentEdgeInsets = UIEdgeInsetsMake(16.0, 16.0, 16.0, 16.0)
self.sizeToFit()
}
}
}
Where this is patientButton.png
Two problems:
contentEdgeInsets
property and sizeToFit
seem to have no effectI guess it's a pretty basic question, but I can't any solution. Any advise?
EDIT 1 as per discussion with Matt below:
What I'm trying to achieve is to get some space around the title of the button. That was my understanding of contentEdgeInsets
but it looks like I'm wrong. Without contentEdgeInsets
this is the rendering of the button
which looks horrible. I want to programmatically get something like this, without having to resize the button in IB
You have misunderstood what contentEdgeInsets
does. For the inset of your background image, you need to implement this method:
override func backgroundRectForBounds(bounds: CGRect) -> CGRect {
return bounds.rectByInsetting(dx: 16, dy: 16)
}
For IBDesignable, what you're doing is structurally correct; if you delete your _setup()
code and replace it with
self.backgroundColor = UIColor.redColor()
the button will in fact be red in IB. So maybe IB just doesn't "do" background images set in code and so on.