how to make uiview animated so it appears slowly from right to left and having two UIButtons on it having images on buttons and one of them image on button will change on button click
[UIView animateWithDuration:0.7f
animations:^ {
CGRect frame = YourView.frame;
frame.origin.x = 0;
YourView.frame = frame;
YourView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);
}
completion:^(BOOL finished) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:5.3];
[UIView commitAnimations];
}];
You can try this code and make changes according to your requirements .
here i create a baseview which moves from right to left and vice versa.
In that baseview you put whatever u want to animate.
set bounceDistance,bounceDuration,animateWithDuration,delay variable according to your requirement.
-(IBAction)rightClicked:(id)sender {
CGRect initalFrame = self.baseView.frame;
initalFrame.origin.x = initalFrame.size.width;
self.baseView.frame = initalFrame;
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(moveFromLeftOrRight:) userInfo:#0 repeats:NO];
}
-(IBAction)leftClicked:(id)sender {
CGRect initalFrame = self.baseView.frame;
initalFrame.origin.x = -initalFrame.size.width;
self.baseView.frame = initalFrame;
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(moveFromLeftOrRight:) userInfo:#1 repeats:NO];
}
-(void)moveFromLeftOrRight:(NSTimer *) timer {
BOOL isLeft = [timer.userInfo boolValue];
CGFloat bounceDistance = 10;
CGFloat bounceDuration = 0.2;
[UIView animateWithDuration:.2 delay:0.0 options:UIViewAnimationOptionAllowAnimatedContent
animations:^{
CGFloat direction = (isLeft ? 1 : -1);
self.baseView.center = CGPointMake(self.baseView.frame.size.width/2 + direction*bounceDistance, self.baseView.center.y);}
completion:^(BOOL finished){
[UIView animateWithDuration:bounceDuration animations:^{
self.baseView.center = CGPointMake(self.baseView.frame.size.width/2, self.baseView.center.y);
}];
}];
}
Assuming you are targeting iPhone.
Set the view's x co ordinate to, say 320(max visible in iPhone) in the storyboard (IB).
x-320 y-0 width-320 height-568
In the viewDidAppear: you can animate and bring the view to the starting co ordinate, say 0. You can do this as follows
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[UIView animateWithDuration:10.f animations:^{
self.view.frame = CGRectMake(0.f, 0.f, 320.f, 568.f);
}];
}
For the buttons you will have to be specific.
Right to Left animation & Left to right animation as-
let firstViewTowardsLeft = UIView(frame: CGRect(x: 0, y: 150, width: 50, height: 50))
firstViewTowardsLeft.backgroundColor = .red
view.addSubview(firstViewTowardsLeft)
UIView.animate(withDuration: 1, delay: 0, options: .repeat, animations: {Bool in
firstViewTowardsLeft.frame = CGRect(x: 100, y: 150, width: 50, height: 50)
}, completion: nil)
let secondViewTowardsLeft = UIView(frame: CGRect(x: 100, y: 100, width: 50, height: 50))
secondViewTowardsLeft.backgroundColor = .red
view.addSubview(secondViewTowardsLeft)
UIView.animate(withDuration: 1, delay: 0, options: .repeat, animations: {Bool in
secondViewTowardsLeft.frame = CGRect(x: 0, y: 100, width: 50, height: 50)
}, completion: nil)
https://developer.apple.com/documentation/uikit/uiview/1622418-animate
Related
I'm trying to animate UIImageView from top to bottom and vice versa.
I tried the code:
Previous value was(y == 0):
laserImageView.frame = CGRect(x: 0, y: 0.0, width: 300.0, height: 300.0)
and want to animate it to 500.0:
UIView.animate(withDuration: 3.0, delay: 0.2, options: [.curveEaseInOut], animations: {
laserImageView.frame = CGRect(x: 0, y: 500.0, width: 300.0, height: 300.0)
}) { (finished) in
if finished {
// Repeat animation from bottom to top
}
}
but when I run my app the UIImageView appears at the last point(y == 500) without any animation, like the initial position was 500.0 but not 0.0.
I do not understand why animation does not work. Any idea?
Try this code:
class ViewController: UIViewController {
let laserImageView = UIImageView(frame: CGRect(x: 0, y: 0.0, width: 300.0, height: 300.0))
override func viewDidLoad() {
super.viewDidLoad()
laserImageView.backgroundColor = UIColor.blue
self.view.addSubview(laserImageView)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
bottom()
}
func bottom() {
UIView.animate(withDuration: 3.0, delay: 0.2, options: [.curveEaseInOut], animations: {
self.laserImageView.frame = CGRect(x: 0, y: 500.0, width: 300.0, height: 300.0)
}) { (finished) in
if finished {
// Repeat animation from bottom to top
self.Up()
}
}
}
func Up() {
UIView.animate(withDuration: 3.0, delay: 0.2, options: [.curveEaseInOut], animations: {
self.laserImageView.frame = CGRect(x: 0, y: self.laserImageView.bounds.origin.y, width: 300.0, height: 300.0)
}) { (finished) in
if finished {
// Repeat animation to bottom to top
self.bottom()
}
}
}
}
One way to do so is take a IBOutlet of top constraint of view which you want to animate and update the value of constraint using the below method:-
- (IBAction)animateButton:(UIButton *)sender {
[UIView transitionWithView:_topView duration:0.8 options:UIViewAnimationOptionRepeat animations:^{
_headerViewTopConstraint.constant = self.view.frame.size.height - 20;
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];
}
For those who wants to do it using code inspite of interface builder can use below answer:-
__weak FirstViewController *weakSelf = self;
[UIView transitionWithView:_topView duration:0.4 options:UIViewAnimationOptionCurveEaseIn animations:^{
//
_topView.frame = CGRectMake(0, 300, _topView.frame.size.width, _topView.frame.size.height);
[weakSelf.view layoutIfNeeded];
} completion:^(BOOL finished) {
//
}];
Please try to post complete question inspite of downvoting the answer :) Thanks
I try to animate an UILabel:
let label: UILabel = UILabel()
var transform = CGAffineTransform.identity
UIView.animate(withDuration: 2, animations: {
self.transform = self.transform.translatedBy(x: 0, y: -150)
self.transform = self.transform.scaledBy(x: 2, y: 2)
self.label.transform = self.transform
})
It works well. I have a button and I added a selector so that when it is pressed, the label animates again:
func performSearch() {
UIView.animate(withDuration: 2, animations: {
self.transform = self.transform.translatedBy(x: 0, y: -300)
self.label.transform = self.transform
})
}
But what it actually does is to scale down the label as in the original state, move it down to the bottom of the screen, then animate, although all I want it to do is to move up. Why?
Transforms can be a little confusing... Because you have scaled the transform, further transforms seem to be "auto-adjusted" by the scaling, but not in a really intuitive or obvious way.
This may help you get further:
// initial animation
UIView.animate(withDuration: 2, animations: {
self.transform = self.transform.translatedBy(x: 0, y: -150)
self.transform = self.transform.scaledBy(x: 2, y: 2)
self.label.transform = self.transform
})
// "resuming" animation
func performSearch() {
let distance: CGFloat = -300 / 2
self.transform = self.transform.translatedBy(x: 0, y: distance)
self.label.transform = self.transform
UIView.animate(withDuration: 2, animations: {
self.transform = self.transform.translatedBy(x: 0, y: distance)
self.label.transform = self.transform
})
}
You can flip the coordinate system to behave like iOS like this...
layer.sublayerTransform = CATransform3DMakeScale(1.0f, -1.0f, 1.0f);
If you want to move it up in performSearch() you need to use a positive y value:
self.transform = self.transform.translatedBy(x: 0, y: 300)
In the above image,A,B,C,D,E are each custom cell,of collection view and i want to zoom in the cell one by one like c cell.
Any suggestion?
Just call this method when your collectionviewcell click
[self animateZoomforCell:cell]; // pass cell as collectionviewcell
-(void)animateZoomforCell:(UICollectionViewCell*)zoomCell
{
[UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
zoomCell.transform = CGAffineTransformMakeScale(1.6,1.6);
} completion:^(BOOL finished){
}];
}
-(void)animateZoomforCellremove:(UICollectionViewCell*)zoomCell
{
[UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
zoomCell.transform = CGAffineTransformMakeScale(1.0,1.0);
} completion:^(BOOL finished){
}];
}
In swift 3 based on Himanshu Moradiya solution:
func animateZoomforCell(zoomCell : UICollectionViewCell)
{
UIView.animate(
withDuration: 0.2,
delay: 0,
options: UIViewAnimationOptions.curveEaseOut,
animations: {
zoomCell.transform = CGAffineTransform.init(scaleX: 1.2, y: 1.2)
},
completion: nil)
}
func animateZoomforCellremove(zoomCell : UICollectionViewCell)
{
UIView.animate(
withDuration: 0.2,
delay: 0,
options: UIViewAnimationOptions.curveEaseOut,
animations: {
zoomCell.transform = CGAffineTransform.init(scaleX: 1.0, y: 1.0)
},
completion: nil)
}
Starting from the right end, I have to fill the color in UITableViewCell (or to say it better, change the background of UITableViewCell starting from right to left in a small duration). How may I achieve this ?
It's quite easy.
Just put a view in the background, starting with a 0 width and on the right of the tableview/tableview cell, then animate it to the full width of the superview.
Code snippet (in form of a Swift playground)
import UIKit
import XCPlayground
let tableView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 200))
tableView.backgroundColor = UIColor.whiteColor()
var animatedBackroundColorView = UIView(frame: CGRect(x: tableView.frame.width, y: tableView.frame.origin.y, width: tableView.frame.width, height: tableView.frame.height))
animatedBackroundColorView.backgroundColor = UIColor.orangeColor()
tableView.addSubview(animatedBackroundColorView)
UIView.animateWithDuration(1) { () -> Void in
animatedBackroundColorView.frame = tableView.frame
}
XCPShowView("identifier", view: tableView)
Rending:
try this
UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(cell.frame.size.width + 1,0,cell.frame.size.width,cell.frame.size.height)];
[backgroundView setBackgroundColor:yourColor];
[cell addSubview:backgroundView];
[UIView animateWithDuration:2.0 animations:^{
CGRect rect = backgroundView.frame;
rect.origin.x = 0;
[backgroundView setFrame:rect];
} completion:NULL];
I need to move UIButtons inside the view when I tap on image, and need to move UIButtons out of the screen when I tap on same image again.
When I tap on a UIImage, 4 UIButtons move inside screen with following code without a problem.
func imageTapped(img: AnyObject)
{UIView.animateWithDuration(0.5,
delay: 0,
options: [.CurveEaseInOut, .AllowUserInteraction],
animations: {
self.imageReceivedTrashCan.center = CGPoint(x: 30, y: 530)
self.imageReceivedRightArrow.center = CGPoint(x: 285, y: 530)
self.imageReceivedForward.center = CGPoint(x: 160, y: 530)
self.imageReceivedCross.center = CGPoint(x: 30, y: 30)
},
completion: { finished in
print("Objects moved!")
})
}
But, I couldn't find a way how can I move UIButtons back to original locations when I click on same image again. Appreciate your help.
Even if this seems really old-school, w/o any autolayout and I randomly guessed you don't change the center's elsewhere and all center's at once:
func imageTapped(img: AnyObject) {
if (self.imageReceivedTrashCan.center == CGPoint(x: 30, y: 530)) {
UIView.animateWithDuration(0.5,
delay: 0,
options: [.CurveEaseInOut, .AllowUserInteraction],
animations: {
self.imageReceivedTrashCan.center = CGPoint(x: -30, y: -530)
self.imageReceivedRightArrow.center = CGPoint(x: -285, y: -530)
self.imageReceivedForward.center = CGPoint(x: -160, y: -530)
self.imageReceivedCross.center = CGPoint(x: -30, y: -30)
},
completion: { finished in
print("Objects moved!")
})
} else {
UIView.animateWithDuration(0.5,
delay: 0,
options: [.CurveEaseInOut, .AllowUserInteraction],
animations: {
self.imageReceivedTrashCan.center = CGPoint(x: 30, y: 530)
self.imageReceivedRightArrow.center = CGPoint(x: 285, y: 530)
self.imageReceivedForward.center = CGPoint(x: 160, y: 530)
self.imageReceivedCross.center = CGPoint(x: 30, y: 30)
},
completion: { finished in
print("Objects moved!")
})
}
}
Firstly, to answer your question :
You can save the initial position for each button then on the second tap you call animateWithDuration:delay:options:animations:completion: and set the position to self.imageReceivedTrashCan.center = initialPosition
You also can try with translation methods from CoreGraphics.
UIView.animateWithDuration(0.5,
delay: 0,
options: [.CurveEaseInOut, .AllowUserInteraction],
animations: {
self.imageReceivedTrashCan.transform = CGAffineTransformMakeTranslation(300, 0)
....
},
completion: { finished in
print("Objects moved!")
})
}
Then on the second tap get back to the Identity transform
UIView.animateWithDuration(0.5,
delay: 0,
options: [.CurveEaseInOut, .AllowUserInteraction],
animations: {
self.imageReceivedTrashCan.transform = CGAffineTransformIdentity
....
},
completion: { finished in
print("Objects moved!")
})
}
But this method is hard coded, you should use autoLayout to make this kind of animations. Look at here
Hope this help you ;)
Select imageView, goto attribute inspector and Check user interaction enabled
UITapGestureRecognizer *TapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(moveMyView:)];
[imageview addGestureRecognizer: TapRecognizer];
- (void) moveMyView:(UITapGestureRecognizer*)sender {
[UIView animateWithDuration:1.0 delay:0.0 options:
UIViewAnimationOptionCurveEaseIn animations:^{
self.imageReceivedTrashCan.center = CGPoint(x: -30, y: -530)
self.imageReceivedRightArrow.center = CGPoint(x: -285, y: -530)
self.imageReceivedForward.center = CGPoint(x: -160, y: -530)
self.imageReceivedCross.center = CGPoint(x: -30, y: -30)
} completion:^ (BOOL completed) {}];
}];
}