Reputation: 8118
I'm trying to create a button that looks like this:
So it has a border and a right imageview.
I subclassed UIButton like this:
class ButtonWithRightImage: UIButton {
override func imageRectForContentRect(contentRect:CGRect) -> CGRect {
var imageFrame = super.imageRectForContentRect(contentRect)
imageFrame.origin.x = CGRectGetMaxX(super.titleRectForContentRect(contentRect)) - CGRectGetWidth(imageFrame)
return imageFrame
}
override func titleRectForContentRect(contentRect:CGRect) -> CGRect {
var titleFrame = super.titleRectForContentRect(contentRect)
if (self.currentImage != nil) {
titleFrame.origin.x = CGRectGetMinX(super.imageRectForContentRect(contentRect))
}
return titleFrame
}
}
And I created my button as follows:
lazy var testButton: ButtonWithRightImage = {
let button = ButtonWithRightImage(forAutoLayout: ())
button.setTitle("Privacy", forState: .Normal)
button.setTitleColor(UIColor.DarkBlue(), forState: .Normal)
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.grey().CGColor
button.setImage(UIImage(named: "arrow"), forState: .Normal)
button.contentHorizontalAlignment = .Left
button.contentEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 0)
return button
}()
Now my button looks like this:
As you can see the image is not aligned with 20 points from the right. I can't figure out how to do this. I'm using autolayout to display the button so I can't just modify the frames I guess.
Upvotes: 2
Views: 362
Reputation: 3259
Swift 3 and above solution based on MinuMaster's answer.
Furthermore, provision is added to set right padding for image and left padding for text from storyboard.
Also, have handled the text length so it should not overlap image.
class ButtonWithRightImage: UIButton {
@IBInspectable var imagePaddingRight: CGFloat = 0.0
@IBInspectable var textPaddingLeft: CGFloat = 0.0
override func imageRect(forContentRect contentRect:CGRect) -> CGRect {
var imageFrame = super.imageRect(forContentRect: contentRect)
imageFrame.origin.x = contentRect.width - imageFrame.width - imagePaddingRight
return imageFrame
}
override func titleRect(forContentRect contentRect:CGRect) -> CGRect {
var titleFrame = super.titleRect(forContentRect: contentRect)
if (self.currentImage != nil) {
titleFrame.origin.x = super.imageRect(forContentRect: contentRect).minX + textPaddingLeft
if titleFrame.size.width > frame.size.width - (imageView?.frame.size.width)! - imagePaddingRight {
titleFrame.size.width = titleFrame.size.width - (imageView?.frame.size.width)! - imagePaddingRight
}
}
return titleFrame
}
}
Upvotes: 0
Reputation: 1457
As your ButtonWithRightImage class need modification to achieve output as per your requirement.
class ButtonWithRightImage: UIButton {
override func imageRectForContentRect(contentRect:CGRect) -> CGRect {
var imageFrame = super.imageRectForContentRect(contentRect)
imageFrame.origin.x = CGRectGetWidth(contentRect) - CGRectGetWidth(imageFrame)
return imageFrame
}
override func titleRectForContentRect(contentRect:CGRect) -> CGRect {
var titleFrame = super.titleRectForContentRect(contentRect)
if (self.currentImage != nil) {
titleFrame.origin.x = CGRectGetMinX(super.imageRectForContentRect(contentRect))
}
return titleFrame
}
}
Issue is you need to minus image width from container width
. Instead of container maxX
value.
Let me know if you have any comment on the same.
Thanks
Upvotes: 4
Reputation: 101
Set imageEdgeInsets for button Like Below code:-
lazy var testButton: ButtonWithRightImage =
{
let button = ButtonWithRightImage(forAutoLayout: ())
button.setTitle("Privacy", forState: .Normal)
button.setTitleColor(UIColor.DarkBlue(), forState: .Normal)
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.grey().CGColor
button.setImage(UIImage(named: "arrow"), forState: .Normal)
button.contentHorizontalAlignment = .Left
button.imageEdgeInsets = UIEdgeInsetsMake(0, 280, 0, 0)
return button
}()
Upvotes: 0