简体   繁体   中英

backgroundImage on UIButton scales wrongly

I'm trying to give my UIButton a new background image when the user pressed the button and then animate the width. Problem is that the button doesn't scale the image (I'm only using retina images).

Before click:

在此输入图像描述

After click:

在此输入图像描述

And the code that makes things happen:

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) {
    }];

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];

i hope this help you...

The way you are creating the Edge Insets, would keep the leftmost 3 and the rightmost 3 poins (or pixels) constant, and it would stretch the head on the button. If you want the head's size to be constant, you have to include it in the left side, leave 1 pixel stretchable and then comes the right side. Assuming your picture's width is 50, you would write:

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

However, this would make your picture positioned in the left side of the button. The solution I recommend would be to use 2 images:

  1. a resizable image containing only the border of the button, set as the button's background image
  2. an image containing only the head, set as the buttons image with constant size

The code would look something like:

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!

I have modified your code on following points:

  • provided complete name of image Profile_Button_Default.png (or .jpg etc),
  • added states for image as in case of normal it these effects will not be appeared in starting of button touched

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) {
                 }];

I think the problem is that your changing the background and then resizing.

The key to getting it working with auto layout is to animate the widthConstraint constant value and also set the background image in an animation.

For example, I have a button on my view name button , I have an IBOutlet to my width constraint named buttonWidth - Below is the code for my buttonPress :

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 with my code above, the key to making it work for me was setting the button background inside an animation also, for some reason if i changed the background image outside the animation it would not set it correctly until the animation completed.

Also setting the frame when using autoLayout didn't work for me, so I animated the constraint constant

Try this, instead of assigning the image as

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

do this

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

no need for setting constraint of resizableImageWithCapInsets.

I had this same problem, but it happened when my app loaded up, I messed around with the button 's attributes in the inspector and if you scroll down and Un-check autoresize subviews it might work, it did for me! Good Luck!

I've had a similar situation resizing subviews when using a nib. Not sure if you are or not, but what fixed my problems was unchecking 'Use Autolayout' on my various views.

Hopefully that fixes your issues.

-Brandon

Could you not make a copy of the image and resize it to the correct button size?

Check out IWasRobbed "s answer in this post.

He has a nice function there for you and claims to use this method for his buttons.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM