BackgroundImage on UIButton scales erroneously

I am trying to give my UIButton a new background image when a user clicks a button and then animate the width. The problem is that the button does not scale the image (I use only retinal images).

Before clicking:

enter image description here

After clicking:

enter image description here

And the code that does things:

UIImage *buttonProfileDefault = [[UIImage imageNamed:@"Profile_Button_Default"] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 3, 3)]; [self.profileButton setBackgroundImage:buttonProfileDefault forState:UIControlStateNormal]; [self.profileButton removeConstraint:self.profileButtonConstraint]; // Animate CGRect originalFrame = self.profileButton.frame; originalFrame.size.width = 40; [UIView animateWithDuration:0.2f animations:^{ self.profileButton.frame = originalFrame; } completion:^(BOOL finished) { }]; 
+6
source share
8 answers

try this code ...

  [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:1.0]; [self.profileButton setBackgroundImage:[UIImage imageNamed:@"Profile_Button_Default"] forState:UIControlStateNormal]; [self.profileButton setBackgroundImage:[UIImage imageNamed:@"Profile_Button_Default"] forState:UIControlStateSelected]; [self.profileButton setFrame:CGRectMake(self.profileButton.frame.origin.x, self.profileButton.frame.origin.y, self.profileButton.frame.size.width + 40, self.profileButton.frame.size.height)]; [UIView commitAnimations]; 

Hope this helps you ...

+3
source

The way you create the Edge tabs will keep the leftmost 3 and rightmost 3-points (or pixels) constant, and it stretches its head on the button. If you want the head size to be constant, you must turn it on the left side, leave 1 pixel stretchable, and then right. Assuming the image width is 50, you should write:

UIImage * buttonProfileDefault = [[UIImage imageNamed:@"Profile_Button_Default"] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 46, 3, 3)];

However, this would make your photo located on the left side of the button. I recommend using two images:

  • a modified image containing only the button border specified as the background image of the button
  • image containing only the head specified as the image of buttons with a constant size

The code looks something like this:

UIImage *backgroundImage = [[UIImage imageNamed:@"border.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 3, 3)]; // in this case you can use 3, 3, 3, 3

[self.profileButton setBackgroundImage:backgroundImage forState:UIControlStateNormal];

UIImage *titleImage = [UIImage imageNamed:@"head.png"];

[self.profileButton setImage:titleImage forState:UIControlStateNormal];

Hope this helps!

+2
source

I changed your code to the following points:

  • provided the full image name Profile_Button_Default.png (or .jpg, etc.),
  • states for the image are added, as in the case of normal, these effects will not be displayed when the button affected

Now check:

 UIImage *buttonProfileDefault = [[UIImage imageNamed:@"Profile_Button_Default.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 3, 3)]; [self.profileButton setBackgroundImage:buttonProfileDefault forState:UIControlStateNormal]; [self.profileButton setBackgroundImage:buttonProfileDefault forState:UIControlStateSelected]; [self.profileButton setBackgroundImage:buttonProfileDefault forState:UIControlStateHighlighted]; [self.profileButton removeConstraint:self.profileButtonConstraint]; // Animate CGRect originalFrame = self.profileButton.frame; originalFrame.size.width = 40; [UIView animateWithDuration:0.2f animations:^{ self.profileButton.frame = originalFrame; } completion:^(BOOL finished) { }]; 
+2
source

I think the problem is that you change the background and then resize.

The key to having it work with automatic layout is to wait for the value of the widthConstraint constant, and also to set the background image in the animation.

For example, I have a button in the name of the name I have an IBOutlet to limit the width named buttonWidth . Below is the code for my button.

 UIImage *imageButton = [[UIImage imageNamed:@"button"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10)]; [UIView animateWithDuration:0.01f animations:^{ [self.button setBackgroundImage:imageButton forState:UIControlStateNormal]; } completion:^(BOOL finished) { [UIView animateWithDuration:1.0f animations:^{ self.buttonWidth.constant = 300; [self.view layoutIfNeeded]; } completion:^(BOOL finished) { }]; }]; 

As you can see in my code above, the key to making it work for me is setting the button background inside the animation, for some reason, if I changed the background image outside the animation, it would not set it correctly until animation completed.

Also setting the frame when using autoLayout did not work for me, so I animated the constant constant

+2
source

Try this instead of assigning the image as

 UIImage *buttonProfileDefault = [[UIImage imageNamed:@"Profile_Button_Default"] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 3, 3)]; 

do it

 UIImage *buttonProfileDefault = [UIImage imageNamed:@"Profile_Button_Default"]; 

no need to set resizableImageWithCapInsets restriction.

+2
source

I had the same problem, but it happened when my application loaded, I messed up with the button attributes in the inspector, and if you scroll down and cancel the autoresize subviews , this might work, it did for me! Good luck

+1
source

I had a similar situation resizing subviews when using a tip. I'm not sure if you exist or not, but what fixed my problems unchecked the "Use autorun" box on my various views.

Hope this fixes your issues.

-Brandon

+1
source

Could not make a copy of the image and resize it to the desired size?

Check out IWasRobbed's answer in this post .

It has a nice feature for you and claims to use this method for its buttons.

+1
source

All Articles