I have a UIButton in a UIViewController that I currently have "fading in" to view when the app is opened. I would like to get the UIButton to slide in from left to right instead though.
I can't figure out how to get it to slide in from left to right and my attempts have failed, even though I've got the "fade in" thing down solid.
Any help you could give me? Thanks! I can add any more code as needed-
ViewController.h
#property (weak, nonatomic) IBOutlet UIButton *buttonOne;
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSTimer *timermovebutton = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(movebutton) userInfo:nil repeats:NO];
[timermovebutton fire];
}
-(void) movebuttontwo
{
buttonTwo.alpha = 0;
[UIView beginAnimations:Nil context:Nil];
[UIView setAnimationDelay:0.5];
[UIView setAnimationCurve:UIViewAnimationTransitionCurlUp];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:1.0];
buttonTwo.alpha = 1.0;
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
[UIView commitAnimations];
}
You need to animate the buttons frame, not use an animation curve.
Since iOS 4, we've had UIView animation blocks:
// first set the UIButton frame to be outside of your view:
// we are only concerned about it's location on the X-axis so let's keep all properties the same
[buttonTwo setFrame:CGRectMake(CGRectGetMaxX(self.view.frame), CGRectGetMinY(buttonTwo.frame), CGRectGetWidth(buttonTwo.frame), CGRectGetHeight(buttonTwo.frame))];
[UIView animateWithDuration:0.5
delay:0
options:UIViewAnimationCurveEaseOut
animations:^{
// set the new frame
[buttonTwo setFrame:CGRectMake(0, CGRectGetMinY(buttonTwo.frame), CGRectGetWidth(buttonTwo.frame), CGRectGetHeight(buttonTwo.frame))];
}
completion:^(BOOL finished){
NSLog(#"Done!");
}
];
There's a good tutorial over at Ray Wenderlich you can check out to learn more.
//Set your button off the screen to the left
yourButton.frame = CGRectMake(-yourButton.frame.size.width, yourButton.frame.origin.y, CGRectGetWidth(yourButton.frame), CGRectGetHeight(yourButton.frame));
//Create the ending frame or where you want it to end up on screen
CGRect newFrm = yourButton.frame;
newFrm.origin.x = 100;
//Animate it in
[UIView animateWithDuration:2.0f animations:^{
yourButton.frame = newFrm;
}];
Related
I'm trying to fade from one image to another, using a SINGLE UIView (Yes! have seen Q&As on stackoverflow, that use 2 UIViews - on top of each other).
I have a current UIView image, would like to fade it out and replace it with another image, and fade the new image in.
I have tried the following: The fading of the first , alone, works.
Attempt #1)
// Fade original image - image already set in Storyboard
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:5.0];
[UIView setAnimationDelegate:self];
[_imgMirror setAlpha:0.0];
[UIView commitAnimations];
// Fade in new image
[_imgMirror setImage:[UIImage imageNamed:#"NewImage"]];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:5.0];
[_imgMirror setAlpha:100.0];
[UIView commitAnimations];
This fades in new image... Old image does not fade. Also tried 'pausing' between the 2 groups of code.
Attempt #2)
UIImage * toImage = [UIImage imageNamed:#"NewImage"];
[UIView transitionWithView:self.imgMirror
duration:0.33f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.imgMirror.image = toImage;
} completion:NULL];
This shows the new image immediately, never fades or 'CrossDissolves'.
Attempt #3)
// Fade original image - image already set in Storyboard
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:5.0];
[UIView setAnimationDelegate:self];
[_imgMirror setAlpha:0.0];
[UIView commitAnimations];
UIImage * toImage = [UIImage imageNamed:#"NewImage"];
[UIView transitionWithView:self.imgMirror
duration:0.33f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.imgMirror.image = toImage;
} completion:NULL];
This has the same result as #2.
Any idea what is wrong?
Try this. It fades the image out, swaps the image without an animation, then fades in with another animation.
CGFloat fadeDuration = 0.5f;
[UIView animateWithDuration:fadeDuration animations:^{
[_imgMirror setAlpha:0.0];
} completion:^(BOOL finished) {
UIImage * toImage = [UIImage imageNamed:#"NewImage"];
_imgMirror.image = toImage;
[UIView animateWithDuration:fadeDuration animations:^{
[_imgMirror setAlpha:1.0];
}];
}];
You cannot "cross fade" from one UIImage to another by setting the .image property of your image view.
You can do it with an "intermediary" image view though.
Assuming you have a UIImageView connected via IBOutlet, and a button connected via IBAction:
//
// CrossFadeViewController.m
//
// Created by Don Mag on 3/7/18.
//
#import "CrossFadeViewController.h"
#interface CrossFadeViewController ()
#property (strong, nonatomic) IBOutlet UIImageView *imgMirror;
#end
#implementation CrossFadeViewController
- (IBAction)didTap:(id)sender {
[self crossFadeTo:#"NewImage"];
}
- (void) crossFadeTo:(NSString *)newImageName {
UIImageView *toImageView;
// create a new UIImageView with the new Image
toImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:newImageName]];
// set the new image view's frame to match the existing one
toImageView.frame = _imgMirror.frame;
// cross-fade / dissolve from the existing image view to the new one
[UIView transitionFromView:_imgMirror
toView:toImageView
duration:0.33
options:UIViewAnimationOptionTransitionCrossDissolve
completion:^(BOOL finished) {
// when animation is finished
// remove the "old" image view from its superview
[_imgMirror removeFromSuperview];
// assign the new image view to the IBOutlet property
_imgMirror = toImageView;
}];
}
#end
I want to make an Menu Animation just as shown below.
I need to have UIButtons inside the menu.
How can i achieve this.
for this animation you should set anchor point by default the anchor point position is (0.5,0.5), so can change the anchor point position:
All geometric manipulations to the view occur about the specified point. For example, applying a rotation transform to a layer with the default anchor point causes the layer to rotate around its center. Changing the anchor point to a different location would cause the layer to rotate around that new point.
self.view.layer.anchorPoint = CGPointMake(0,0);
self.view.transform = CGAffineTransformMakeScale(0.001,0.001);
[UIView animateWithDuration:1.0 animations:^{
self.view.transform = CGAffineTransformIdentity;
}];
Please add the follow code on button click:
[UIView animateWithDuration:1
animations:^{
myView.transform = CGAffineTransformMakeScale(1.5, 1.5); }
completion:^(BOOL finished) {
[UIView animateWithDuration:1
animations:^{
myView.transform = CGAffineTransformIdentity;
}]; }];
It will work for you.
Create Super class SuperViewController.m
Add this method
- (void)viewDidLoad {
[super viewDidLoad];
//Here u can set image also in navigation bar
UIBarButtonItem *buttonC = [[UIBarButtonItem alloc]initWithTitle:#"Word" style:UIBarButtonItemStylePlain target:self action:#selector(GeTVAlue)];
[self.navigationItem setLeftBarButtonItem:buttonC];
}
-(void)GeTVAlue{
UIView *paintView=[[UIView alloc]initWithFrame:CGRectMake(-350, -350, 350, 350)];
[paintView setBackgroundColor:[UIColor yellowColor]];
[self.view addSubview:paintView];
[UIView animateWithDuration:1
animations:^{
paintView.transform = CGAffineTransformMakeScale(2.5, 2.5); }
completion:^(BOOL finished) {
[UIView animateWithDuration:1
animations:^{
paintView.transform = CGAffineTransformIdentity;
}]; }];
}
Then Inherit your Super class in your class
#interface TheerdViewController : SuperViewController
If u have any question fill free ask me.
Thnak you
EDITED Question:
So i have this code for some custom buttons (clouds) that move from right to left and animate when they are tapped.
- (void)viewDidLoad
{
[super viewDidLoad];
// Move UIView
cloudAnimate.center = CGPointMake(400.0, 90.0);
cloudAnimate1.center = CGPointMake(400.0, 150.0);
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[UIView animateWithDuration:10.0
delay:1.0
options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAllowUserInteraction
animations:^{
cloudAnimate.center = CGPointMake(100.0, 90.0);
}
completion:NULL];
[UIView animateWithDuration:8.0
delay:0.0
options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAllowUserInteraction
animations:^{
cloudAnimate1.center = CGPointMake(100.0, 150.0);
}
completion:NULL];
}
The code does what i want so am happy there but if that View is on and you exit the app and re enter to that view the clouds are stuck at the end point. I have to leave the view and come back in to it to get them to start again.
Is there a way that when you exit the view the clouds pause where they are and when you go back in they are where they were and continue to animate as normal?
Is this your problem?
- (void)**viewDidAppear**:(BOOL)animated
{
[super **viewDidLoad**];
Move the lines
cloudAnimate.center = CGPointMake(400.0, 90.0);
cloudAnimate1.center = CGPointMake(400.0, 150.0);
into viewWillAppear:. This way the buttons` positions will be reset every time you're reopening the app.
I have a method that drops down a UIView. That works fine. How would I go about having it slide back up when the button is touched a second time?
I also need to deactivate it somehow so that it doesn't repeat the animation if it's already displayed.
- (void)slideDownTableView {
self.tableViewCities = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.tableViewCities.frame = CGRectMake(0,0,300,180);
self.tableViewCities.autoresizingMask = ( UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth );
self.tableViewCities.dataSource = self;
self.tableViewCities.delegate = self;
self.tableViewCities.backgroundColor = [UIColor whiteColor];
UIView *myview=[[UIView alloc] initWithFrame: CGRectMake(10, 0,300,180)];
myview.backgroundColor=[UIColor redColor];
[myview addSubview:self.tableViewCities];
[self.view addSubview:myview];
myview.frame = CGRectMake(10, 0,300,-180); // offscreen
[UIView animateWithDuration:0.5
animations:^{
myview.frame = CGRectMake(10, 0,300,180); // final location move
}];
}
iOS provides autoreverse property by which animation reverses automatically.
UIViewAnimationOptionAutoreverse will give you an effect as the animation reverses .
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionAutoreverse
animations:^{
// do whatever animation you want, e.g.,
someView.frame = someFrame1;
}
completion:NULL];
Using BeginFromCurrentState option worked for me.
if(!enabled){
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationTransitionCurlUp
animations:^{
myview.frame = CGRectMake(10, 0,300,180);
}
completion:nil];
enabled=YES;
}
else{
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationTransitionCurlUp
animations:^{
myview.frame = CGRectMake(10, 0,300,-180);
}
completion:nil];
enabled=NO;
}
With a simple BOOL to store the current state of the sliding UIView you can achieve this.
The initial state is not visible if I understand well? So initially the BOOL citiesVisible is set to N0, then the button's action check its value, and performs a different animation accordingly. Simple.
Finally, I also disable the button during the animation to prevent the user to trigger a second animation while a first one is already performing.
I rewrote a bit your code to follow some best practices, and improve readability/maintainability:
Setting up the views beforehand because the button's action responsibility shouldn't be to setup the views, but only to animate them.
Changed the signature of the target action, that's my personal style guide to state in the sender's name and the ControlEvent, it makes it more tidy when you have multiple buttons/actions ;). Also per Apple guidelines, methods receiving actions should have one "id" parameter, the sender.
Store the frames in variables (you could also have them as #define, that'd be even better I think), so you don't have to hard-code them twice, it reduces the risk of breaking the animation by having a view sliding to different positions...
Code update:
#interface ViewController ()
#property (nonatomic, strong) UIButton *showCitiesButton;
#property (nonatomic, strong) CGRect citiesInitialFrame;
#property (nonatomic, strong) CGRect citiesVisibleFrame;
#property (nonatomic, strong) UITableView *tableViewCities;
#property (nonatomic, strong) UIView *citiesContainer;
#property (nonatomic, strong) BOOL citiesVisible;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Setting up the cities view
self.citiesInitialFrame = CGRectMake(10, -180, 300, 180);
self.citiesVisibleFrame = CGRectMake(10, 0, 300, 180);
self.tableViewCities = [[UITableView alloc] init ...];
self.citiesContainer = [[UIView alloc] init ...];
// ...
self.citiesVisible = NO;
[self.showCitiesButton addTarget:self
action:#selector(showCitiesButtonDidTouchUpInside:)
forControlEvents:UIControlEventTouchUpInside];
}
- (void)showCitiesButtonDidTouchUpInside:(id)sender
{
[self.showCitiesButton setEnabled:NO];
if (self.citiesVisible)
{
// Cities view is visible, sliding it out of the screen
[UIView animateWithDuration:0.5
animations:^{
self.citiesContainer.frame = self.citiesInitialFrame;
} completion:^(BOOL finished) {
self.citiesVisible = NO;
[self.showCitiesButton setEnabled:YES];
}];
}
else
{
// Cities view is not visible, sliding it in
[UIView animateWithDuration:0.5
animations:^{
self.citiesContainer.frame = self.citiesVisibleFrame;
} completion:^(BOOL finished) {
self.citiesVisible = YES;
[self.showCitiesButton setEnabled:YES];
}];
}
}
#end
You can reverse UIView animation with this code:
if (isMarked) {
[UIView animateWithDuration:3
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
self.transform=CGAffineTransformMakeScale(1.1, 1.1);
}
completion:nil];
} else {
[UIView animateWithDuration:3
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
self.transform=CGAffineTransformIdentity;
}
completion:nil];
}
I need my app to move an image when the user clicks on a certain button. This works perfectly:
ViewController.m
#import "ndpViewController.h"
#interface ndpViewController ()
#property (nonatomic, retain) IBOutlet UIImageView *image;
-(void)movetheball;
#end
#implementation ndpViewController
#synthesize image;
int ballx, bally;
-(void)movetheball {
[UIView beginAnimations: #"MovingTheBallAround" context: nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration: 1.0];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
image.frame = CGRectMake(ballx,bally,image.frame.size.width,image.frame.size.height);
[UIView commitAnimations];
}
- (void)viewDidLoad {
}
- (IBAction)calculatePush:(id)sender {
ballx = 600;
bally = 800;
[self movetheball];
}
#end
But as soon as the app has to do something else (when user clicks the button), like adding a text to a label, which I do in this way:
_lizfwLabel.text=[NSString stringWithFormat:#"%.2f",lizfw];
then the app will move the image only upon clicking the button a second time.
Any idea on why is this happening? Thank you!
Try to use another one method to animate UIView's in iOS. Apple advices to use [UIView animate...] rather then old style [UIView begin/commitAnimations];.
In your case you should replace movetheball method code to that one:
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
CGRect frame = image.frame;
frame.origin.x = ballx;
frame.origin.y = bally;
image.frame = frame;
} completion:nil];