backgroundImage on UIButton scales wrongly - iphone

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:
a resizable image containing only the border of the button, set as the button's background image
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.

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.

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!

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.

Related

UIButton adding color with animation

What i want to do is, when the user clicks the button then the button should fill with color with animation from bottom to top.
I tried this which added the color but the animation effect was not added.
float originalY = btn.frame.origin.y;
float originalH = btn.bounds.size.height;
[UIView animateWithDuration:3.0f
delay:1.0f
options:UIViewAnimationOptionTransitionFlipFromBottom
animations:^{
btn.frame = CGRectMake(btn.frame.origin.x, (originalY + originalH), btn.bounds.size.width, 0);
[btn setBackgroundImage:[UIImage imageNamed:#"Screen Shot 2012-11-07 at 4.22.30 PM.png"] forState:UIControlStateNormal];
[btn setTitleColor:[[UIColor alloc]initWithRed:38.0/255.0 green:38.0/255.0 blue:38.0/255.0 alpha:1.0] forState:UIControlStateNormal];
} completion:^(BOOL finished) {
}];
The best solution would be to subclass UIButton and add a method that changes the background image's alpha value from 0 to 1.
Or you could just override the drawRect method and fill up the background with a color there.
i think you probably do something like this, i used UIlabel it may also work for UIButton to .
#import <QuartzCore/QuartzCore.h>
....
'theLabel.layer.backgroundColor = [UIColor whiteColor].CGColor;
[UIView animateWithDuration:2.0 animations:^{
theLabel.layer.backgroundColor = [UIColor greenColor].CGColor;
} completion:NULL];'`

How to do the move the images like marquee in html in iphone

i am developing one application.In that i have 10 images .i want to move that images from right to left like as a marquee effect in HTML.That images are moving infinite number of times.So please tell me how to move that images from left to right.
I'd try something like this:
- (void)startAnimatingImages
{
for (UIImage* aImage in yourImageArray)
{
[self animateLabelToTheRight:aImage];
}
}
- (void)animateLabelToTheRight:(UIView *)yourView
{
[UIView animateWithDuration:0.3
animations:^{ view.frame = CGRectMake(view.frame.origin.x + 35, view.frame.origin.y, image.frame.size.width, image.frame.size.height); }
completion:^{ [self animateLabelToTheLeft:yourView] } ];
}
- (void)animateLabelToTheLeft:(UIView *)yourView
{
[UIView animateWithDuration:0.3
animations:^{ yourView.frame = CGRectMake(yourView.frame.origin.x - 35, yourView.frame.origin.y, yourView.frame.size.width, yourView.frame.size.height); }
completion:^{ [self animateLabelToTheRight:yourView] } ];
}
As stated in #Dev's answer this can be done through animation, however if you're going to animate it theres no need to change the image if you only want to move it.
This code for example takes a photo of your choosing and moves it from the top left of the screen to the bottom left and can be modified to move right to left, and is already set up to repeat infinitely with [UIView setAnimationRepeatCount:-1];.
In achieving a marquee effect, the best way I can think of to handle that would be to make the images fully animate off screen before the animation ends and resets, creating the illusion that the image went off one side of the screen and came in the other.
- (void)animateImage
{
UIImageView *myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"myImage.png"]];
[self.view addSubview:myImageView];
[myImageView setFrame:CGRectMake(0, 0, 50, 50)];
[UIView beginAnimations:#"myAnimation" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDelegate:self];
[UIView setAnimationRepeatCount:-1];
// [UIView setAnimationDidStopSelector:#selector(callSomeThingElse)];
[myImageView setFrame:CGRectMake(0, 430, 50, 50)];
[UIView commitAnimations];
}
Animation is required for this type of moving image. if you try this code ,your problen is solve:
UIImageView *animationimage;
animationimage.animationImages = [NSMutableArray arrayWithObjects:
[UIImage imageNamed:#"Splash1.png"],
[UIImage imageNamed:#"Splash2.png"],
[UIImage imageNamed:#"Splash3.png"],
[UIImage imageNamed:#"Splash4.png"],
[UIImage imageNamed:#"Splash5.png"],nil];
// all frames will execute in 1.0 seconds
animationimage.animationDuration = 1.0;
// repeat the annimation forever
animationimage.animationRepeatCount = 0;
remember one thing you have different sequential image is require link in my code splash%i.
i hope ,helpful for you.

Accessing the current position of UIView during animation

I am trying to find the current position of an iPhone ImageView that is animating across the screen.
I create and animate the imageView like so
-(IBAction)button:(UIButton *)sender{
UIImageView *myImageView =[[UIImageView alloc] initWithImage:
[UIImage imageNamed:#"ball.png"]];
myImageView.frame = CGRectMake(0, self.view.frame.size.height/2, 40, 40);
[self.view addSubview:myImageView];
[myArray addObject:myImageView];
[UIView animateWithDuration:.5
delay:0
options:(UIViewAnimationOptionAllowUserInteraction) // | something here?)
animations:^{
myImageView.frame = CGRectOffset(myImageView.frame, 500, 0);
}
completion:^(BOOL finished){
[myArray removeObject:myImageView];
[myImageView removeFromSuperview];
[myImageView release];
}
];
}
then to detect the current CGPoint of the imageView I call this method every 60th of a second
-(void)findPoint{
for (UIImageView *projectile in bullets) {
label.text = [NSString stringWithFormat:#"%f", projectile.center.x];
label2.text = [NSString stringWithFormat:#"%f", projectile.center.y];
}
}
However this only gives me the point where the animation ends, I want to get the current CGPoint of the image that is animating across the screen. Is there an option that I need to apply other than UIViewAnimationOptionAllowUserInteraction to do this? If not, how do I get the current position of an animating imageView?
You can use the presentationLayer - a property of the CALayer that "provides a close approximation to the version of the layer that is currently being displayed". Just use it like this:
CGRect projectileFrame = [[projectile.layer presentationLayer] frame];
Swift 5:
Get temporary position and size (CGRect) during the animation with:
let currentFrame = projectileFrame.layer.presentation()!.frame

UIView beginanimations: subview shall not animate

Hi I have a UIView to which I add a UIButton in its initWithFrame: method like this:
UIButton * dropB = [UIButton buttonWithType:UIButtonTypeRoundedRect];
dropB.frame = CGRectMake(190, 22, 52, 22);
dropB.backgroundColor = [UIColor clearColor];
dropB.titleLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:11];
[dropB setTitle:#"DROP" forState:UIControlStateNormal];
[dropB addTarget:viewController
action:#selector(dropSelectedObject)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:dropB];
Then, as I try to animate the view with a resizing like this:
[UIView beginAnimations:#"MoveIt" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationBeginsFromCurrentState:YES];
self.dropButton.center = CGPointMake(self.dropButton.center.x + 80, self.dropButton.center.y -10);
self.frame = CGRectMake(0, 0, WIDTH, HEIGHT);
self.center = CGPointMake(CENTER_X, CENTER_Y);
[UIView commitAnimations];
The button only gets translated to a new position which is the previous one (the original coordinates were relative to the view i guess). How can I make it translate to the point i specify?
Ok it was pretty simple (and stupid).
Since I needed the UIButton to remain at a fixed height I had to specify what space was 'flexible' while resizing. This can be done using the autoresizingMask property of an UIView this way:
dropB.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleBottomMargin;
and not calling anithing among the animation instructions

Animated moving UIButton not responding to touches/taps while moving

I'm trying to animate a UIButton to move up the screen. At any point the user can touch it. However, it doesn't seem to respond to touches while moving, only at the start and end of its animation. I guess this is because the button itself isn't moving, just the image of it. Any ideas how I can solve this? Here's my code so far. Thanks!
- (void)viewDidLoad {
[self newBubble];
[super viewDidLoad];
}
- (void)newBubble {
UIButton *bubble = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
bubble.frame = CGRectMake(10, 380, 50, 50);
UIImage *bubbleImage = [UIImage imageNamed:#"bubble.png"];
[bubble setBackgroundImage:bubbleImage forState:UIControlStateNormal];
bubble.imageView.contentMode = UIViewContentModeScaleAspectFit;
[bubble addTarget:self action:#selector(bubbleBurst:) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:bubble];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:5.0];
CGAffineTransform newTransform = CGAffineTransformMakeScale(1.5, 1.5);
bubble.transform = CGAffineTransformTranslate(newTransform, 10, -200);
[UIView commitAnimations];
}
- (IBAction)bubbleBurst:(id)sender {
NSLog(#"Bubble burst");
UIButton *bubbleBurst = sender;
[bubbleBurst removeFromSuperview];
}
The +[UIView animateWithDuration:delay:options:animations:completion:] method takes a UIViewAnimationOptions argument. If you include UIViewAnimationOptionAllowUserInteraction, you should be able to press the button while it animates:
[UIView animateWithDuration:5.0
delay:0.0
options:UIViewAnimationOptionAllowUserInteraction
animations:^{
CGAffineTransform newTransform = CGAffineTransformMakeScale(1.5, 1.5);
bubble.transform = CGAffineTransformTranslate(newTransform, 10, -200);
} completion:nil];
Well after posting a similar question, I found the answer here
Basically, you have to move the button frame by frame using an NSTimer. In my case I was worried there would be too many NSTimers involved moving each button, but in the end I used a single timer which loops through an array of buttons and moves them all one by one.
I'm pretty sure you would have to use Core Animation if you want the button to respond to touches while it is moving, but I have never done this so this is really more a tip then an answer!
I agree. I think the problem is that you're not using Core Animation. I can't believe you couldn't figure that out for yourself.