3

My issue is pretty simple yet I can't find a solution. I have a UIButton which has a title and image. I want image position to be fixed no matter what happens so I set it this way:

[button setImageEdgeInsets:UIEdgeInsetsMake(0.f, 0.f, 0.f, IS_IPHONE ? 20.f : 60.f)];

I do not set any position for the button's titleLabel.

What happens next is I set new title for the button, the title label shrinks or expands to fit new text and surprisingly it makes the image move, so it is obvious that despite applied image edge insets the image position depends on the label's frame. I see two solutions that can be used:

1) Make image independent of label's frame

2) Set fixed size for the label

but I don't know how to implement neither of them. Can you please give me some advice how do I resolve this issue?

Andrey Chernukha
  • 21,488
  • 17
  • 97
  • 161

3 Answers3

6

You can subclass UIButton and manage rects for image & title. Override below methods and return appropriate rects for image & title as per your requirement.

-(CGRect)imageRectForContentRect:(CGRect)contentRect;

-(CGRect)titleRectForContentRect:(CGRect)contentRect;
Rahul Wakade
  • 4,765
  • 2
  • 23
  • 25
5

To fix this in Interface Builder, take the following steps.

First set the image and the text for the button. Then you'll want to create some space between the image and the button. This takes two steps: 1) Set the left content inset to, say, 10 points 2) Then set the image inset to minus 10 points

Step 1: Set content inset left property to 10 points

Step 2: Set image inset left property to minus 10 points

Then to force the button to expand text to the right, only add a constraint to the left side:

Add constraints for top and left

The reason that you can't just use the title left inset, is because that way your title will be truncated:

enter image description here

This is because title and image insets aren't taken into account for the intrinsic button sizing, only content inset is used.

Bart van Kuik
  • 4,704
  • 1
  • 33
  • 57
1

It is because of setting image inset and title inset of UIButton. You can try as above suggestion given by @mehul patel, @Nirav BHatt and @The dude.

Or you may try this way : here we assume that your image is first and then titleLabel in button.

 //-------- Create button ---------
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(50, 100, 100, 40)];
btn.backgroundColor = [UIColor cyanColor];

//----- Create imageview --------
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 20, 20)];
imgView.image = [UIImage imageNamed:@"your_image_name.png"];

//----- Create Name label -----------
UILabel *nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(imgView.frame.origin.x+imgView.frame.size.width+10, 0, 80, btn.frame.size.height)];
nameLabel.backgroundColor = [UIColor blueColor];
nameLabel.textAlignment = NSTextAlignmentLeft;
nameLabel.textColor = [UIColor whiteColor];
nameLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:14];
nameLabel.text = @"your title label";
nameLabel.adjustsFontSizeToFitWidth = YES;
[nameLabel sizeToFit];

//-------- Resize button frame ----------
btn.frame = CGRectMake(btn.frame.origin.x, btn.frame.origin.y, nameLabel.frame.origin.x+nameLabel.frame.size.width+10, btn.frame.size.height);
[btn addSubview:nameLabel];
[btn addSubview:imgView];

you can add image and label vice versa (first label and then image) and then update frame of button according to it.

VRAwesome
  • 4,721
  • 5
  • 27
  • 52