I would like to place an icon left of the two lines of text such that there's about 2-3 pixels of space between the image and the start of text. The control itself is Center aligned horizontally (set through Interface Builder)
The button would resemble something like this:
| |
|[Image] Add To |
| Favorites |
I'm trying to configure this with contentEdgeInset, imageEdgeInsets and titleEdgeInsets to no avail. I understand that a negative value expands the edge while a positive value shrinks it to move it closer to the center.
I tried:
[button setTitleEdgeInsets:UIEdgeInsetsMake(0, -image.size.width, 0, 0)];
[button setImageEdgeInsets:UIEdgeInsetsMake(0, button.titleLabel.bounds.size.width, 0, 0)];
but this doesn't display it correctly. I've been tweaking the values but going from say -5 to -10 on the left inset value doesn't appear to move it in expected manner. -10 will scoot the text all the way to the left so I expected -5 to scoot it half way from the left side but it doesn't.
What's the logic behind insets? I'm not familiar with image placements and related terminology.
I used this SO question as a reference but something about my values isn't right.
UIButton: how to center an image and a text using imageEdgeInsets and titleEdgeInsets?
Best Answer
I'm a little late to this party, but I think I have something useful to add.
Kekoa's answer is great but, as RonLugge mentions, it can make the button no longer respect
sizeToFit
or, more importantly, can cause the button to clip its content when it is intrinsically sized. Yikes!First, though,
A brief explanation of how I believe
imageEdgeInsets
andtitleEdgeInsets
work:The docs for
imageEdgeInsets
have the following to say, in part:I believe that this documentation was written imagining that the button has no title, just an image. It makes a lot more sense thought of this way, and behaves how
UIEdgeInsets
usually do. Basically, the frame of the image (or the title, withtitleEdgeInsets
) is moved inwards for positive insets and outwards for negative insets.OK, so what?
I'm getting there! Here's what you have by default, setting an image and a title (the button border is green just to show where it is):
When you want spacing between an image and a title, without causing either to be crushed, you need to set four different insets, two on each of the image and title. That's because you don't want to change the sizes of those elements' frames, but just their positions. When you start thinking this way, the needed change to Kekoa's excellent category becomes clear:
But wait, you say, when I do that, I get this:
Oh yeah! I forgot, the docs warned me about this. They say, in part:
But there is a property that can help, and that's
contentEdgeInsets
. The docs for that say, in part:That sounds good. So let's tweak the category once more:
And what do you get?
Looks like a winner to me.
Working in Swift and don't want to do any thinking at all? Here's the final version of the extension in Swift: