I'm trying to make my app show an image (PNG) in the middle of a screen when a button is pressed and then make it fade out after a few seconds. How would I be able to do this? Also it is a small png so how can i just make it show in its original size rather then stretch it out to fit the whole screen? Any tip, suggestion or answer is greatly appreciated!
Also I am new to this site so could you please tip me or help me improve this question as some people think it is not complete. Thank you everyone for your generous answers! :)
Initialize an UIImageView with an UIImage:
// Assuming MyImage.png is part of the project's resources.
UIImage *image = [UIImage imageNamed:#"MyImage.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// Add imageView to a parent view here.
[UIView animateWithDuration:0.2f delay:3.0f options:0
animations:^{imageView.alpha = 0.0;}
completion:^{[imageView removeFromSuperview];}];
Here is the code for showing image for the few seconds on button press:
in your button action add following code:
imageView.image=yourImage;
[self performSelector:#selector(waitAndGo) withObject:nil afterDelay:5];
here is the implementation for the waitAndGo:
-(void)waitAndGo
{
imageView.hidden=YES;
}
NSArray *animationArray = [NSArray arrayWithObjects:[UIImage imageNamed:#"myImage.png"], nil];
[NSTimer scheduledTimerWithTimeInterval:.75 target:self selector:#selector(crossfade) userInfo:nil repeats:YES];
mainImageView.animationImages = animationArray;
mainImageView.animationDuration = 4.5; //mainImageView is instance of UIImageView
mainImageView.animationRepeatCount = 0;
[mainImageView startAnimating];
CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:#"contents"];
crossFade.autoreverses = YES;
crossFade.repeatCount = 1;
crossFade.duration = 1.0;
and the target method:
- (void) crossfade {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; // user dependent transition acn be set here
mainImageView.alpha = !mainImageView.alpha;
[UIView commitAnimations];
}
Related
I want my image to fade IN, not out. With this code, it's backwards. Any help?
[UIView animateWithDuration:3.0 animations:^{
self.circleOne.alpha = 0.0;
}];
If your circleOne has alpha 0(invisible) all you need to do is set the alpha to 1:
[UIView animateWithDuration:3.0 animations:^{
self.circleOne.alpha = 1.0;
}];
Edit:
If you want to make a animation before it appears on screen, you can set the alpha to 0 before adding the circleOne the it's parentview.
Assuming that circleOne is an UIImageView it would be like this:
circleOne = [[UIImageView alloc] initWithImage: [UIImage imageNamed:#"imageName,jpg"]];
circleOne.alpha = 0.0;
[parentView addSubview: circleOne];
//run the animation explained before
Im stuck trying to animate a table view smoothly which has an autolayout contraint. I have a reference to the constraint "keyboardHeight" in my .h and have linked this up in IB. All i want to do is animate the table view with the keyboard when it pops up. Here is my code:
- (void)keyboardWillShow:(NSNotification *)notification
{
NSDictionary *info = [notification userInfo];
NSValue *kbFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardFrame = [kbFrame CGRectValue];
CGFloat height = keyboardFrame.size.height;
[UIView animateWithDuration:animationDuration animations:^{
self.keyboardHeight.constant = -height;
[self.view setNeedsLayout];
}];
}
The thing is the animation block is instantaneous and I see white space appear before the keyboard has finished its animation. So basically I see the white background of the view as the keyboard is animating. I cannot make the animation last for as long as the keyboard is animating.
Am i approaching this the wrong way? Thanks in advance!
Try it this way:
self.keyboardHeight.constant = -height;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];
Remember this pattern because this should be the correct way to update constraint-based layouts (according to WWDC). You can also add or remove NSLayoutConstraints as long as you call setNeedsUpdateConstraints after.
If you're using UITableViewController, keyboard size should be automatically accommodated by iOS to adjust the contentInsets. But if your tableView is inside a UIViewController, you probably wanted to use this:
KeyboardLayoutConstraint in the Spring framework. Simplest solution I've found so far.
Try the next code. In this case table view lays out at the bottom edge of the screen.
- (void)keyboardWillShow:(NSNotification *)notification { // UIKeyboardWillShowNotification
NSDictionary *info = [notification userInfo];
NSValue *keyboardFrameValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardFrame = [keyboardFrameValue CGRectValue];
BOOL isPortrait = UIDeviceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
CGFloat keyboardHeight = isPortrait ? keyboardFrame.size.height : keyboardFrame.size.width;
// constrBottom is a constraint defining distance between bottom edge of tableView and bottom edge of its superview
constrBottom.constant = keyboardHeight;
// or constrBottom.constant = -keyboardHeight - in case if you create constrBottom in code (NSLayoutConstraint constraintWithItem:...:toItem:...) and set views in inverted order
[UIView animateWithDuration:animationDuration animations:^{
[tableView layoutIfNeeded];
}];
}
- (void)keyboardWillHide:(NSNotification *)notification { // UIKeyboardWillHideNotification
NSDictionary *info = [notification userInfo];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
constrBottom.constant = 0;
[UIView animateWithDuration:animationDuration animations:^{
[tableView layoutIfNeeded];
}];
}
The approach I took is to add a view which follows the size of the keyboard. Add it below your tableview, or text input or whatever and it will push things up when the keyboard appears.
This is how I set up the view hierarchy:
NSDictionary *views = #{#"chats": self.chatsListView, #"reply": self.replyBarView, #"fakeKeyboard":self.fakeKeyboardView};
[self.view addVisualConstraints:#"V:|-30-[chats][reply][fakeKeyboard]|" views:views];
And then the key bits of the keyboard-size-following view look like this:
- (void)keyboardWillShow:(NSNotification *)notification
{
// Save the height of keyboard and animation duration
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardRect = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
self.desiredHeight = CGRectGetHeight(keyboardRect);
self.duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
[self animateSizeChange];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
self.desiredHeight = 0.0f;
[self animateSizeChange];
}
- (CGSize)intrinsicContentSize
{
return CGSizeMake(UIViewNoIntrinsicMetric, self.desiredHeight);
}
- (void)animateSizeChange
{
[self invalidateIntrinsicContentSize];
// Animate transition
[UIView animateWithDuration:self.duration animations:^{
[self.superview layoutIfNeeded];
}];
}
The nice thing about letting this particular view handle its resizing is that you can let the view controller ignore it, and you can also re-use this view any place in your app you want to shift everything up.
The full file is here:
https://gist.github.com/shepting/6025439
I'm working on a page-based iPhone app using Xcode 4.4 with ARC and have been stuck on this for awhile. On a certain page, a UIImageView finger needs to slide up and point to something and then slide left off the screen. This works as expected when I run it once, but when I turn the page and go back - there is now 2 fingers sliding about 0.5 seconds out of sync with eachother.
Here's the code:
-(void)fingerSwipeUp:(UIImageView *)imageView
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[imageView setCenter:CGPointMake(213.75,355.5)];
[UIView commitAnimations];
}
-(void)fingerSwipeLeft:(UIImageView *)imageView
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
[imageView setCenter:CGPointMake(-80,355.5)];
[UIView commitAnimations];
}
UIImageView *finger = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"finger.png"]];
// position finger off the screen
[finger setFrame:CGRectMake(142.5,480,152.5,243)];
[self.view addSubview:finger];
[self performSelector:#selector(fingerSwipeUp:) withObject:finger afterDelay:6];
[self performSelector:#selector(fingerSwipeLeft:) withObject:finger afterDelay:8];
Any help greatly appreciated
I'm guessing that you're creating the "finger" view in ViewDidAppear()? If that's the case, every time the page is turned (hidden) and then gone back to, you're adding another arrow (subview). What about this instead:
if (finger == nil) {
finger = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"finger.png"]];
[finger setFrame:CGRectMake(142.5,480,152.5,243)];
[self.view addSubview:finger];
}
[self performSelector:#selector(fingerSwipeUp:) withObject:finger afterDelay:6];
[self performSelector:#selector(fingerSwipeLeft:) withObject:finger afterDelay:8];
If you've got a number of animations in a sequence, you might find it easier to use the block-based UIView animation syntax:
[UIView animateWithDuration:1.0 delay:6.0 options:UIViewAnimationCurveEaseInOut animations:^{
// animation 1
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 delay:8.0 options:UIViewAnimationCurveEaseInOut animations:^{
// animation 2
}];
}];
This will only start animation 2 after animation 1 has finished, so you don't need to worry about allowing for the duration of animation 1 when delaying animation 2.
I try to make an animation with an image in my view but it doesn't work: my image is at the final position without animation.
UIImage *myImg = [UIImage imageNamed : #"Img72.png"];
UIImageView *myImgView =[ [UIImageView alloc] initWithImage: myImg ];
myImgView.frame= CGRectMake(250,50,72,72);
[self.view addSubview:myImgView];
[UIView animateWithDuration:0.5
delay: 0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
[UIView setAnimationRepeatCount:100.0];
[UIView setAnimationRepeatAutoreverses:YES];
myImgView.frame= CGRectMake(50,250,72,72);
}
completion:NULL];
[myImgView release];
The same animation code work perfectly in another view. I finally find that it's come from the way I display the view with this code:
FlipsideViewController *controller = [[[FlipsideViewController alloc] initWithNibName:#"FlipsideViewController" bundle:nil] autorelease];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; //KO
[self presentModalViewController:controller animated:YES];
The problem is the modalTransitionStyle. When I comment the line (with //KO) it finally works. I test the other transition style and all the other works (UIModalTransitionStyleCoverVertical, UIModalTransitionStyleCrossDissolve, UIModalTransitionStylePartialCurl)
I made an viewDidLoadProject (Utility App) and just add the animation code in the two view in viewDidLoad method.
Where is the problem? Is it an Apple bug? How can I have a flip transition AND my animation working in the second view?
Here is my example project: http://dl.dropbox.com/u/9204589/testFlipAnimation.zip
That seems more natural to start to play with the interface when all the system stuff is done, didAppear must be used for that purpose i believe (yes, it works :))
FlipsideViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)viewDidAppear:(BOOL)animated
{
UIImage *myImg = [UIImage imageNamed : #"Img72.png"];
UIImageView *myImgView =[ [UIImageView alloc] initWithImage: myImg ];
myImgView.frame= CGRectMake(250,50,72,72);
[self.view addSubview:myImgView];
[UIView animateWithDuration:0.5
delay: 0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
[UIView setAnimationRepeatCount:100.0];
[UIView setAnimationRepeatAutoreverses:YES];
myImgView.frame= CGRectMake(50,250,72,72);
}
completion:NULL];
[myImgView release];
[super viewDidAppear:animated];
}
I want to animate my background after a view got loaded in my iOS application. This works with solid colors, but I'm not able to let it work using background images. This is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
[UIView animateWithDuration:5.0 animations:^{
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"background.png"]];
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"background_dark.png"]];
}];
[UIView commitAnimations];
}
Does anyone know the correct way to do this?
Thanks
You animate things like this:
view.backgroundColor = INITIAL COLOR
[UIView animateWithDuration:5.0 animations:^{
view.backgroundColor = FINAL COLOR
}];
The animate method animates the change from the current state to whatever you set up in the animation block. The animation block is not a list of steps.
Therefore, I think what you want is this:
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"background.png"]];
[UIView animateWithDuration:5.0 animations:^{
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"background_dark.png"]];
}];
Also, do NOT call commitAnimations afterward, that's only if you're using the old-style beginAnimations method. Read the documentation, and don't just call methods to see if they work.
Not all properties can be animated like this. It is very likely that a background image is one of them. What you can do is have a second view on top with the new image and animate its alpha from 0 to 1.
Ty this:
[UIView animateWithDuration:5.0 animations:^{
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"background.png"]];
} completion:^(BOOL finished)
{
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"background_dark.png"]];
}];