iPhone: How to resize a png file during an animation - iphone

Is there any way to resize (in my case increase the width) of an PNG file in an animation? This would need to result into a distortion of the original PNG (in my case, I try to get the PNG fatter).
My code so far is:
pageShadow = [UIImage imageNamed:#"pageshadow.png"]; // load our image resource
pageShadowView = [[UIImageView alloc] initWithImage:pageShadow];
[UIView beginAnimations:#"shadowMove" context:nil]; // Begin animation
[UIView setAnimationDuration:4.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
//[pageShadowView setFrame:CGRectMake(0, 0, CGRectGetWidth(pageShadowView.frame), CGRectGetHeight(pageShadowView.frame))];
[UIView commitAnimations];
But I can't think of a command to increase the width of my PNG. I guess this is not possible as long as it is confined to an UIView, right? I'd be grateful for any suggestions of how to tackle this problem. Thanks, and sorry if this is really obvious or basic.

to do what you want you probably want to add a transform to the view.
try something like
[pageShadowView setTransform:CGAffineTransformMakeScale (2, 1)];

Related

Animating UIView frame size change with autoresizing subviews

I have a UIView which contains two subviews. I would like to change the superview's frame size with an animation and have the subviews' sizes change in accordance with their autoresize masks.
[UIView beginAnimations:#"Resize" context:nil];
[UIView setAnimationDuration:1.0];
CGRect frame = self.myView.frame;
frame.size.height += 30.0;
self.myView.frame = frame;
[UIView commitAnimations];
The view self.myView is resized over 1 second as expected, but the subviews are resizing immediately. Does anyone know why this is happening and how I might make the subviews animate their resizing as well?
From my googling around, I think it might have something to with the contentMode property. Unfortunately, I'm not really clear as to what that property does. Any help would be much appreciated.
It would have been hard for someone else to give you the correct answer w/o seeing your code though I would have asked you what you are doing after [UIView commitAnimations]. Nevertheless, glad you figured it out. I suggest you use the block animations. They make this type of mistake much easier to avoid by using a completion block. Example:
[UIView animateWithDuration:1.0
animations:^{
CGRect frame = self.myView.frame;
frame.size.height += 30.0;
self.myView.frame = frame;
}
completion:^(BOOL finished){
// whatever you need to do when animations are complete
}];
OK, so I figured out the issue after reading the answer to the following question: Animating a UIView frame, subview UIScrollView doesn't always animate
I basically was doing some work after I scheduled the animation which was causing -layoutSubviews to be called on each of my subviews which automatically caused those views to be arranged at the end point of the animation. By scheduling my animation after this work was done I was able to solve my problem.

How to decrease the width of a frame of an UIImage gradually without distorting it?

I think this is a very basic question, but I am struggling with this one.
I have a screenshot (an UIImage) which I put into an UIView (called screenShotView in my sample below). I want to get rid of this screenShotView by gradually revealing what is behind this screenShotView. Right now my screenShotView SQUEEZES to the left, but I would like its FRAME to become less and less until the screenShotView is no longer seen (without Squeezing).
This is my code. If I did the same transformation with an UITextView (instead of an UIImage) it would work exactly how I would like it to behave (without transformation).
Perhaps I don't get the concept of framing UIImages?
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:10];
[screenShotView setFrame:CGRectMake(0, 0, 0, 480)];
[UIView commitAnimations];
And this is how it looks like in the middle of the animation:
And this is how I would like it to look like in the middle of the animation:
This is the code updated to Codo's suggestions (see below), with the result that I have no animation anymore. The blue screen simply pops up once the button is pressed. I guess that I am doing something wrong with adding the subviews -- the problem appears to be that no subviews are added and can therefore not disappear:
-(IBAction)showNextText
{
screenShotView = [[UIImageView alloc] initWithImage:[self screenshot]];
[screenShotView setFrame:CGRectMake(0, 0, 320, 480)];
[screenShotScrollView setFrame:CGRectMake(0, 0, 320, 480)];
[self.view addSubview:screenShotScrollView];
[screenShotScrollView addSubview:screenShotView];
screenShotScrollView.scrollEnabled = NO;
[self setUpNextText];
[self removeOldText];
}
-(void)setUpNextText
{
NSString* secondText = #"This is the second text shown if the user clicks next.";
textView.text = secondText;
textView.textColor = [UIColor redColor];
textView.backgroundColor = [UIColor blueColor];
}
-(IBAction)removeOldText{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:5];
[screenShotScrollView setFrame:CGRectMake(0,0,320,480)];
[UIView commitAnimations];
}
Answer to question
It's actually very simple: I've made a sample app to get the star wars(just calling it here) transition working. For simplicity I'll just call the two views firstView and secondView. firstView is shown (would be your screenshot) and secondView will slide in from the left. I've put a button on each view to animate the transition, which is wirde to doTransition. The important part is to set the sliding in view's properties clipsToBounds = YES and autoresizesSubviews = NO. That's it. I'll post some screenshots.
- (void)viewDidLoad
{
[super viewDidLoad];
secondView.frame = CGRectMake(0, 0, 0, 480);
secondView.clipsToBounds = YES;
secondView.autoresizesSubviews = NO;
[self.view addSubview:firstView];
[self.view addSubview:secondView];
}
- (IBAction)doTransition
{
[UIView animateWithDuration:1.0
animations:^{
self.secondView.frame = CGRectMake(0,
0,
320,
480);
}];
}
Research on page curl
I did some research on the page turn / curl effect. Mainly this is all present in iOS, with little effort you can create the iBook page turn effect, but it's accessing private methods and classes. I still encourage anyone to have a look at it, cause it might some day be opened.
Apple's iBooks Dynamic Page Curl - Demo App by Steven Troughton-Smith
Leaves - An App with a custom page curl by Tom Brow, tried, compiled and looks nice!
App Store-safe Page Curl animations - Article on Tom Brow's Leaves App which has been branched (twoPages) by the author Ole Begemann
Implementing iBooks page curling using a conical deformation algorithm - With a MacOS Demo App, very professional and advanced, though not an option for a quick shot still inspiring. Download the App!
The anatomy of a page curl - Mathematical approach
I guess you have to put your upper view into a UIScrollView. Then you set the content size to be the same as the size of the UIScrollView and disable scrolling.
Next you do your original animation (setFrame) on the UIScrollView.
Basically, you then use the UIScrollView to introduce a separate coordinate system for the inner view. When the outer view (the scroll view) is made smaller, it will not distort the inner view, but clip it.
CGRect fillRect = self.view.bounds;
leftImageView.clipsToBounds = YES;
leftImageView.contentMode = UIViewContentModeTopLeft;
leftImageView.frame = fillRect;
rightImageView.clipsToBounds = YES;
rightImageView.contentMode = UIViewContentModeTopRight;
rightImageView.frame = CGRectMake(fillRect.size.width, 0, 0, fillRect.size.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:3];
leftImageView.frame = CGRectMake(0, 0, 0, fillRect.size.height);
rightImageView.frame = fillRect;
[UIView commitAnimations];
Don't animate the frame but the center. See the documentation here.
Also, if you only need iOS 4 compatibility, use -animateWithDuration:animations:
[UIView animateWithDuration:10
animations:^{ screenShotView.center = CGPointMake(x, y) } ];
I'm not sure I fully understand how you want your view to disappear.
If it's supposed to become more and more transparent, use the following code (instead of setFrame):
[screenShotView setAlpha: 0.0f];
If it's supposed to become smaller and smaller (but keep its center), then try:
[screenShotView setFrame:CGRectMake(screenShotView.frame.x, screenShotView.frame,y, 0, 0)];

animation speed is different between beginAnimations and using animations block

I am trying to convert some animation code that uses beginAnimations to use animation blocks. The problem that I am having is that when I use the animations blocks the animations goes much faster and I cannot seem to adjust the speed by changing the duration value
This is what I started with originally:
birdFly.image = [UIImage imageNamed: #"bird1.png"];
[self.view addSubview:birdFly];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:20];
birdFly.frame = CGRectMake(-1116,27,111,48);
[UIView commitAnimations];
[birdFly release];
This is what I tried first to replace what I had above. Using this code the animation is much faster than what it was using the original code. Even changing the duration does not seem to change the speed at all:
birdFly.image = [UIImage imageNamed: #"bird1.png"];
[self.view addSubview:birdFly];
[UIView animateWithDuration:20
animations:^{
birdFly.frame = CGRectMake(-1116,27,111,48);
}];
I also tried this, thinking I needed a completion block, but the speed was still just as fast compared with what I had originally when I wasn't using blocks.
birdFly.image = [UIImage imageNamed: #"bird1.png"];
[self.view addSubview:birdFly];
UIViewAnimationOptions options = UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction;
[UIView animateWithDuration:20 delay:0.0 options:options animations:^
{
birdFly.frame = CGRectMake(-1116,27,111,48);
} completion:nil];
Is the code all doing the same thing? Am I just missing something very simple here? I thought increasing the duration would make the bird go slower and decreasing it would make it go faster, but it doesn't seem to have any impact t all when change it using blocks.
Any guidance would be appreciated.
Thanks.
Aaron
If your animation block is occurring within another animation block, -animateWithDuration:animations: will inherit the duration of the outer block. Try adding UIViewAnimationOptionOverrideInheritedDuration to the options list (and possibly UIViewAnimationOptionOverrideInheritedCurve if you need to override the curve too).

Animated stretch of an image frame (iPhone)

So I'm trying to animate an image stretching from a zero width to full size while fading in. The fade in comes across fine, but for whatever reason the thing appears at the full frame at the start of the animation, instead of growing as the alpha effect happens. My code is as follows:
[UIView beginAnimations:#"FadeButtons" context:nil];
[UIView setAnimationDuration:.9];
[UIView setAnimationDelay:0.300];
batteryLife.alpha = 1;
batteryLife.frame = CGRectMake(40, 71, 240, 128);
[UIView commitAnimations];
Any advice on changing a frame in an animated fashion? I don't want to scale the entire image, I want to "unveil" it. Thanks.
Perhaps the frame is already that size before beginAnimations? Try setting the frame immediately before beginAnimations to the smaller size, like batteryLife.frame = CGRectMake(40, 71, 0, 128);

iPhone - UIView Animation not looping correctly

Hey all, got a little problem here and can't figure out what I am doing wrong. I am trying to animate a UIView up and down repeatedly. When I start it, it goes down correctly and then back up but then immediately shoots to the "final" position of the animation. Code is as follows:
UIImageView *guide = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.png"]];
guide.frame = CGRectMake(250, 80, 30, 30);
[self.view addSubview:guide];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:2];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationBeginsFromCurrentState:YES];
guide.frame = CGRectMake(250, 300, 30, 30);
[UIView setAnimationRepeatCount:10];
[UIView commitAnimations];
Thanks in advance!
This is an old question, but in case anyone is looking at this you can just use a fractional repeat count to end on the desired state. If you're animating from A to B and using auto reverse, each repeat will look like this A -> B -> A. Since you want to end on B on the last animation and not A, just do this to make the last repeat only go halfway (to B):
[UIView setAnimationRepeatCount:10.5];
That's it!
It's a 'feature', not a bug. It's really annoying, but it looks like unless Apple says otherwise, this is how UIView Animations are expected to work.
See this answer: setAnimationRepeatAutoreverses not behaved as I expected
You may set setAnimationDidStopSelector to a custom function and in the custom function you can set up more animations (even recursively). See my answer to another question here.
Usually I will define an animation structure (AnimationPath in the example) to coordinate the whole animation (say, by a counter).