Currently I am creating an App when you first launch it, there is some Introduction Text and 2 Buttons. 1 Button to skip the Tutorial and the other one to do the Tutorial. I want that these 2 Buttons and those Labels appear after a certain Time and with an Fade In animation. Could anyone give me some code examples? I already tried searching but the results weren't helpful for me.
I Updatet some Code. Now looks like this:
.h File:
#interface startViewController : UIViewController {
IBOutlet UIButton *notourb;
IBOutlet UIButton *tourb;
IBOutlet UILabel *welcomeLabel;
}
- (void)shownotourb;
- (void)showtourb;
- (void)showwLabel;
And the .m File (I will only show the code from the buttons because I figured out how to do the Labels in another way):
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelector:#selector(shownotourb) withObject:nil afterDelay:2.0];
[self performSelector:#selector(showtourb) withObject:nil afterDelay:2.5];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)shownotourb {
[UIView animateWithDuration:10.0
delay:1.0
options:UIViewAnimationCurveEaseInOut
animations:^ {
[self.view addSubview:notourb];
}
completion:^(BOOL finished){}];
}
- (void)showtourb {
[UIView animateWithDuration:10.0
delay:1.0
options:UIViewAnimationCurveEaseInOut
animations:^ {
[self.view addSubview:tourb];
}
completion:^(BOOL finished){}];
}
create a method which will add the buttons to the view, and use the performSelector:afterDelay method to add them like this:
in your viewDidLoad:
[self performSelector:#selector(addButtonsToView) withObject:nil afterDelay:5.0];
and add this method to add your buttons:
-(void)addButtonsToView
{
[UIView animateWithDuration:10.0
delay:1.0
options:UIViewAnimationCurveEaseInOut
animations:^ {
[self.view addSubview:button1];
[self.view addSubview:button2];
}
completion:^(BOOL finished){}];
}
hope it helps :)
Related
I am trying to animate a UITextView to expand the to the width of its containing UIToolbar.
But it animates weird, jumping around.
Can anyone help me make understand why my textbox jumps around?
#define ANIMATION_DURATION 0.5
#define ANIMATION_DELAY 0.03
#interface WebViewController () <UITextFieldDelegate>{
CGRect URLBAR_DEFAULT;
}
-(void)viewDidLoad{
self.txtURLBar = [[UITextField alloc] init];
self.txtURLBar.bounds = CGRectMake(0, 0, 100, 30);
self.txtURLBar.delegate = self;
self.txtURLBar.backgroundColor = [UIColor lightGrayColor];
self.txtURLBar.clearButtonMode = UITextFieldViewModeWhileEditing;
URLBAR_DEFAULT = self.txtURLBar.frame; //KEEP A REFRENCE TO THE ORIGINAL SIZE
}
//START EDITING EXPAND TO FULL WIDTH
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[UIView animateWithDuration:ANIMATION_DURATION delay:ANIMATION_DELAY options:UIViewAnimationOptionCurveLinear animations:^{
[_txtURLBar setFrame:CGRectMake(3, URLBAR_DEFAULT.origin.y, self.view.frame.size.width - 10, URLBAR_DEFAULT.size.height)];
} completion:^(BOOL finished) {
}];
}
//END EDITING SHRINK BACK TO SMALL SIZE
- (void)textFieldDidEndEditing:(UITextField *)textField {
[UIView animateWithDuration:ANIMATION_DURATION delay:ANIMATION_DELAY options:UIViewAnimationOptionCurveEaseOut animations:^{
[_txtURLBar setFrame:CGRectMake(URLBAR_DEFAULT.origin.x, URLBAR_DEFAULT.origin.y, URLBAR_DEFAULT.size.width, URLBAR_DEFAULT.size.height)];
} completion:^(BOOL finished) {
}];
}
The problem may be due to the frame being set in textFieldDidBeginEditing, textFieldDidEndEditing is different. I've done the small POC with same code of yours as below. It's working fine.
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITextField *resizeableTextField;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//START EDITING EXPAND TO FULL WIDTH
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[UIView animateWithDuration:0.5 delay:0.03 options:UIViewAnimationOptionCurveLinear animations:^{
self.resizeableTextField.frame = CGRectMake(CGRectGetMinX(self.resizeableTextField.frame), CGRectGetMinY(self.resizeableTextField.frame), self.resizeableTextField.frame.size.width + 40, CGRectGetHeight(self.resizeableTextField.frame));
} completion:^(BOOL finished) {
}];
}
//END EDITING SHRINK BACK TO SMALL SIZE
- (void)textFieldDidEndEditing:(UITextField *)textField {
[UIView animateWithDuration:0.5 delay:0.03 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.resizeableTextField.frame = CGRectMake(CGRectGetMinX(self.resizeableTextField.frame), CGRectGetMinY(self.resizeableTextField.frame), self.resizeableTextField.frame.size.width - 40, CGRectGetHeight(self.resizeableTextField.frame));
} completion:^(BOOL finished) {
}];
}
#end
So i have the following function
- (void)setMoreMenuHidden:(BOOL)hidden animated:(BOOL)animated completion:(void(^)(BOOL))completion
{
if (!hidden)
{
[self.view layoutIfNeeded];
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:0.5f animations:^
{
[self.view layoutIfNeeded];
[_profileInfoVC viewWillLayoutSubviews];
}];
}
}
and within _profileInfoVC i have it doing
-(void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[self.view layoutIfNeeded];
self.pictureImageView.layer.cornerRadius = self.pictureImageView.frame.size.width/2;
self.pictureImageView.clipsToBounds = YES;
}
So i am aware that layers are ignored within the animation blocks but I assume this also means updating at all since it remains quite square during and after the animation. Is there a solution to this that does not require me also creating a Core Animation for just the layer?
So it seems the block you are interested in this regard is the Completion block.
- (void)setMoreMenuHidden:(BOOL)hidden animated:(BOOL)animated completion:(void(^)(BOOL))completion
{
if (!hidden)
{
[self.view layoutIfNeeded];
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:0.5f animations:^
{
[self.view layoutIfNeeded];
}
completion:^(BOOL finished)
{
[_profileInfoVC viewWillLayoutSubviews];
}];
}
}
the above seems to have fixed my issue, also i was never really a fan of directly calling viewWillLayoutSubviews directly so that line has been changed to [_profileInfoVC.view setNeedsLayout];
I have a simple animation to fade out an image but it is not working. The method is being called but no animation. What frameworks are required in the project for this? Think that might be the issue since the image just goes right to alpha:0 with no animation.
#import "TutorialViewController.h"
#interface TutorialViewController ()
#end
#implementation TutorialViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self popupImage];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)popupImage
{
NSLog(#"It worked");
_imageView.hidden = NO;
_imageView.alpha = 1.0f;
// Then fades it away after 2 seconds (the cross-fade animation will take 0.5s)
[UIView animateWithDuration:1
delay:2
options:UIViewAnimationOptionCurveEaseIn
animations:^{
_imageView.alpha = .0f;
}
completion:^(BOOL finished) {
// Once the animation is completed and the alpha has gone to 0.0, hide the view for good
_imageView.hidden = NO;
}];
}
In the code below, the subview (cloud) oscillates on the location given.
On tapping that subview while oscillation, it moves out of the bounds to the right side, then moves in from the left.
But the tap gesture is not working on the whole subview, it works only on the right-side end of the oscillating subView.
I want slide out and in of cloud to work, whenever the whole subview of cloud is tapped.
Below is code of .h and .m file respectively.
File : OscillatingCloudsViewController.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface OscillatingCloudsViewController : UIViewController
{
IBOutlet UIView *movingCloud1;
UIImage *cldImg;
}
- (IBAction)animateCloud;
- (IBAction)animateCloudBegin;
#end
File : OscillatingCloudsViewController.m
#import "OscillatingCloudsViewController.h"
#implementation OscillatingCloudsViewController
- (void) viewWillAppear:(BOOL)animated
{
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGestureAnimateCloud)];
tapGesture.numberOfTapsRequired = 1;
tapGesture.numberOfTouchesRequired = 1;
tapGesture.cancelsTouchesInView = YES;
[movingCloud1 addGestureRecognizer:tapGesture];
movingCloud1.userInteractionEnabled = YES;
[super viewWillAppear:
animated];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self animateCloud];
}
- (IBAction) animateCloud
{
cldImg = [UIImage imageNamed:#"cloud1.png"];
movingCloud1=[[UIView alloc]initWithFrame:CGRectMake(50, 50, cldImg.size.width, cldImg.size.height)];
[movingCloud1 setBackgroundColor:[UIColor colorWithPatternImage:cldImg]];
[self.view addSubview:movingCloud1];
movingCloud1.userInteractionEnabled = YES;
[self viewWillAppear:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:5];
[UIView setAnimationRepeatCount:HUGE_VALF];
[UIView setAnimationRepeatAutoreverses:YES];
CGPoint pos = movingCloud1.center;
pos.x = 220.0f;
movingCloud1.center = pos;
[UIView commitAnimations];
}
- (void) animateCloudHidden
{
[movingCloud1 setHidden:YES];
}
- (IBAction)animateCloudBegin
{
movingCloud1.frame = CGRectMake(-100, 50, cldImg.size.width, cldImg.size.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationRepeatAutoreverses:NO];
CGPoint pos = movingCloud1.center;
pos.x = cldImg.size.width;
movingCloud1.center = pos;
[UIView commitAnimations];
}
- (IBAction) tapGestureAnimateCloud
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationRepeatAutoreverses:NO];
movingCloud1.center = CGPointMake(1100.0f, 81.5f);
[UIView commitAnimations];
[self performSelector:#selector(animateCloudBegin) withObject:nil afterDelay:2.0f];
[self performSelector:#selector(animateCloudHidden) withObject:nil afterDelay:3.0f];
[self performSelector:#selector(animateCloud) withObject:nil afterDelay:3.0f];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
I have understood your problem. In viewwillApper you are assing the Gesture and in inside animateCloud method your allocating your movingCloud1 UIView.
For implementing this you need to fallow the bello steps.
In ViewdidLoad you need to allocate and add the movingCloud1 view to you self.view.
After add the Gesture to movingCloud1 view.
Your tapGesture will work now. So inside your tapgesture method just you need to set the animation for your movingCloud1 view
Trying to get to grips with Xcode and seem to be making some progress over the last few weeks.
Does anyone know a way that a custom button can do a different set of animations on a second click.
So let say I have a custom button and its of Mario, when i click it he runs from the middle of the screen and out of the right hand side of the screen and then runs back in to the middle from the left of the screen, he also makes noise.
I have achieved this using this code:
- (IBAction)marioRunning_clicked:(id)sender
{
[UIView animateWithDuration:1.50 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
marioRunning.center = CGPointMake(350.5, 456.0);
} completion:^(BOOL finished) {
if (finished) {
[UIView animateWithDuration:0.00 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
marioRunning.center = CGPointMake(-30.5, 456.0);
} completion:^(BOOL finished) {
if (finished) {
[UIView animateWithDuration:1.50 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
marioRunning.center = CGPointMake(160.0, 456.0);
} completion:^(BOOL finished) {
if(finished) // NSLog ( #"Finished !!!!!" );
marioRunning.center = CGPointMake(160.0, 456.0);
}];
}
}];
}
}];
marioRunning.imageView.animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:#"mario-running2"],[UIImage imageNamed:#"mario-running3"],nil];
marioRunning.imageView.animationDuration = 0.15;
marioRunning.imageView.animationRepeatCount = 19;
[marioRunning.imageView startAnimating];
}
How could I make him do a second set of animations on the next click? For example instead of running from left to right, if i tap him the second time he will Jump up and down?
Use the selected state of the button to decide which animation to do
-(void)buttonClicked:(UIButton*)button
{
if(button.selected)
{
[self doAnimation1];
}
else
{
[self doAnimation2];
}
button.selected = !button.selected;
}
This might be overkill, but here's a cool way to do what you want:
Make a subclass of UIButton, and let's call it DDDMarioButton:
typedef void (^DDDAnimationBlock)(UIButton *button);
#interface DDDMarioButton : UIButton
- (void)addAnimationBlockToQueue:(DDDAnimationBlock)block;
#end
Then in DDDMarioButton.m:
#interface DDDMarioButton ()
#property (nonatomic, strong) NSMutableArray *animationQueue;
#end
#implementation DDDMarioButton
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (void)buttonPressed:(id)button
{
DDDAnimationBlock block = self.animationQueue[0];
block(self);
[self.animationQueue removeObjectAtIndex:0];
}
- (void)addAnimationBlockToQueue:(DDDAnimationBlock)block
{
if(!self.animationQueue)
{
self.animationQueue = [NSMutableArray new];
}
[self.animationQueue addObject:block];
}
#end
and then wherever you create your buttons, you add each step one by one:
DDDMarioButton *button = [[DDDMarioButton alloc] initWithFrame:CGRectZero];
[button addAnimationBlockToQueue:^(UIButton *button) {
// perform some animation
}];
[button addAnimationBlockToQueue:^(UIButton *button) {
// perform another animation
}];
And that should do it. I haven't tested this, you'll probably need some configuration, but that's pretty much the idea.