I\'m trying to create a button which has some text beneath the icon (sorta like the app buttons) however it seems to be quite difficult to achieve. Any ideas how can I go ab
I took a combination of the answers here and came up with one that seems to be working for me, in Swift. I don't love how I just overrode the insets, but it works. I'd be open to suggested improvements in the comments. It seems to work correctly with sizeToFit()
and with auto layout.
import UIKit
/// A button that displays an image centered above the title. This implementation
/// only works when both an image and title are set, and ignores
/// any changes you make to edge insets.
class CenteredButton: UIButton
{
let padding: CGFloat = 0.0
override func layoutSubviews() {
if imageView?.image != nil && titleLabel?.text != nil {
let imageSize: CGSize = imageView!.image!.size
titleEdgeInsets = UIEdgeInsetsMake(0.0, -imageSize.width, -(imageSize.height + padding), 0.0)
let labelString = NSString(string: titleLabel!.text!)
let titleSize = labelString.sizeWithAttributes([NSFontAttributeName: titleLabel!.font])
imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + padding), 0.0, 0.0, -titleSize.width)
let edgeOffset = abs(titleSize.height - imageSize.height) / 2.0;
contentEdgeInsets = UIEdgeInsetsMake(edgeOffset, 0.0, edgeOffset, 0.0)
}
super.layoutSubviews()
}
override func sizeThatFits(size: CGSize) -> CGSize {
let defaultSize = super.sizeThatFits(size)
if let titleSize = titleLabel?.sizeThatFits(size),
let imageSize = imageView?.sizeThatFits(size) {
return CGSize(width: ceil(max(imageSize.width, titleSize.width)), height: ceil(imageSize.height + titleSize.height + padding))
}
return defaultSize
}
override func intrinsicContentSize() -> CGSize {
let size = sizeThatFits(CGSize(width: CGFloat.max, height: CGFloat.max))
return size
}
}