I've seen posts regarding right alignment but I can't get left-alignment to work. I want the button to take up the width of the screen, with the image on the left and the title/text in the center.
This does not work (at least reliably):
button.titleLabel.textAlignment = UITextAlignmentCenter; [button setImageEdgeInsets:UIEdgeInsetsMake(0, -60.0, 0, 0)]; button.frame = CGRectMake((self.view.frame.size.width - w ) / 2, self.view.frame.size.height - 140.0, self.view.frame.size.width - 10.0, 40.0);
This solution works with Swift 3 and respects original content and image edge insets while keeping the title label always centered in the available space, which makes much easier adjusting margins.
It overrides titleRect(forContentRect:)
method and returns the correct frame:
@IBDesignable class LeftAlignedIconButton: UIButton { override func titleRect(forContentRect contentRect: CGRect) -> CGRect { let titleRect = super.titleRect(forContentRect: contentRect) let imageSize = currentImage?.size ?? .zero let availableWidth = contentRect.width - imageEdgeInsets.right - imageSize.width - titleRect.width return titleRect.offsetBy(dx: round(availableWidth / 2), dy: 0) } }
The following insets:
Would result in this:
Deprecated previous answer
This works in most scenarios, but some layouts cause layoutSubviews
to recursively call itself in an endless loop, so use with caution.
@IBDesignable class LeftAlignedIconButton: UIButton { override func layoutSubviews() { super.layoutSubviews() contentHorizontalAlignment = .left let availableSpace = UIEdgeInsetsInsetRect(bounds, contentEdgeInsets) let availableWidth = availableSpace.width - imageEdgeInsets.right - (imageView?.frame.width ?? 0) - (titleLabel?.frame.width ?? 0) titleEdgeInsets = UIEdgeInsets(top: 0, left: availableWidth / 2, bottom: 0, right: 0) } }
This code would do the same but aligning the icon to the right edge:
@IBDesignable class RightAlignedIconButton: UIButton { override func layoutSubviews() { super.layoutSubviews() semanticContentAttribute = .forceRightToLeft contentHorizontalAlignment = .right let availableSpace = UIEdgeInsetsInsetRect(bounds, contentEdgeInsets) let availableWidth = availableSpace.width - imageEdgeInsets.left - (imageView?.frame.width ?? 0) - (titleLabel?.frame.width ?? 0) titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: availableWidth / 2) } }
The right allignment version uses semanticContentAttribute
so it requires iOS 9+.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With