In my app, I have a scrollview with "paging enabled" and when I chose a page an imageview start its animation in this way
- (void) beginWinAnimation{
[UIView animateWithDuration:2.5
animations:^{successView.alpha = 1.0;}
completion:^(BOOL finished){
[UIView animateWithDuration:2.5
animations:^{successView.alpha = 0;}];
}];}
During this animation I can see the scrollview under this successView and I can move scrollview page; I want that during animation you can't move the scrollview but only when animation is finished, is it possible?
Yes it's possible. When the animation starts set [scrollView setScrollEnabled:NO]; After your animation is complete set it back to YES.
So in your code, it will look like -
- (void) beginWinAnimation{
[scrollView setScrollEnabled:NO];
[UIView animateWithDuration:2.5
animations:^{
successView.alpha = 1.0;
}
completion:^(BOOL finished){
[UIView animateWithDuration:2.5
animations:^{successView.alpha = 0;}
completion:^(BOOL finished){
[scrollView setScrollEnabled:YES];
}];
}];}
See if this works.
Related
I'm trying to run an example to test this function. I have a label an a button in the storyBoard and I have referenced the bottom constraint of the label in the view controller. When I use the button I want the label to move with an animation but it moves without it. Here's the code of the button:
- (IBAction)sd:(id)sender {
[UIView animateWithDuration:0.5f animations:^{
self.constraint.constant += 50;
}];
}
I know how to use it in swift but I'm having problems in objective c and I know it will be just for a little mistake... Any help?
This is not the right way of animating a UI component constrained with Autolayout. You should first update the constraint, then call layoutIfNeeded within the animation block:
self.constraint.constant += 50;
[UIView animateWithDuration:0.5f animations:^{
[self.view layoutIfNeeded];
}];
Use this
self.constraint.constant += 50;
[UIView animateWithDuration:0.5f
animations:^{
[self.view layoutIfNeeded];
}];
Try this setNeedsLayout helps in some cases.
self.constraint.constant += 50;
[UIView animateWithDuration:0.5f
animations:^{
[self.view setNeedsLayout];
}
completion:^(BOOL finished) {
}];
My goal is simple and I have achieved this previously which is why I'm resorting to asking my question here.
I am trying to animate a subview. Simple enough. The view ends up exactly where I want it to be after the animation is over. The only problem is:
whatever I do the animation duration is completely ignored. It happens instantly.
- (void)callToDismissView:(UIView *)view {
[self.view addSubview:view];
[self dismissViewControllerAnimated:NO completion:nil];
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^(void){
CGRect frame = self.view.frame;
frame.origin.x = frame.size.width;
view.frame = frame;
} completion:^(BOOL finished){
[view removeFromSuperview];
}];
}
Now I have tried different frames and durations to see if the view was animated at all and it always ends up where I need it to be. Only instantly...
EDIT:
The above code is being called by a delegate in the dismissed view controller like so:
- (void)dismissSelf {
if (self.delegate && [self.delegate respondsToSelector:#selector(callToDismissScan)]) {
[self.delegate callToDismissScan];
}
}
And that method itself is triggered by a notification.
I must admit that some things are happening during the transition between the two controllers that I don't fully understand. (And I would very much like to understand them...)
You can try
[self.view layoutIfNeeded];
like this
- (void)callToDismissView:(UIView *)view {
[self.view addSubview:view];
[self dismissViewControllerAnimated:NO completion:nil];
[self.view layoutIfNeeded];
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^(void){
CGRect frame = self.view.frame;
frame.origin.x = frame.size.width;
view.frame = frame;
[self.view layoutIfNeeded];
} completion:^(BOOL finished){
[view removeFromSuperview];
}];
}
Maybe you need try like this.
- (void)callToDismissView:(UIView *)view {
[self.view addSubview:view];
CGRect frame = self.view.frame;
frame.origin.x = frame.size.width;
[UIView animateWithDuration:0.3 delay:0.3
options:UIViewAnimationOptionCurveEaseInOut animations:^(void){
view.frame = frame;
}
completion:^(BOOL finished){
[view removeFromSuperview];
//[self dismissViewControllerAnimated:NO completion:nil];//uncomment if need.
}];
}
It seems there was no way in hell I could animate the transition in the presenting view controller and so the simplest way to resolve the issue was to animate the transition in the presented view controller before it is being dismissed.
The way I did this was by casting the delegate to a view controller. It was then easy to add it's view as a sub-view of my presented view controller and animate it like so:
- (void)dismissSelf {
UIView *dummyView = [ScreenCapper captureScreenIn: self];
UIViewController *presentingViewController = (UIViewController *)self.delegate;
[self.view.window addSubview: presentingViewController.view];
[self.view.window addSubview: dummyView];
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^(void){
dummyView.frame = CGRectMake(dummyView.frame.size.width, dummyView.frame.origin.y, dummyView.frame.size.width, dummyView.frame.size.height);
} completion:^(BOOL finished){
if (self.delegate && [self.delegate respondsToSelector:#selector(callToDismissView)]) {
[self.delegate callToDismissView];
}
}];
}
And in the presenting view controller all that was left to do was to dismiss the presented view controller without animations.
- (void)callToDismissView {
[self dismissViewControllerAnimated:NO completion:nil];
}
With the following code I'm showing a view with an animation on a button click.
UIViewController *modalView = self.pageViewController;
[self.view addSubview:modalView.view];
[UIView animateWithDuration:1 animations:^{
CGRect currentRect = modalView.view.frame;
currentRect.origin.y = 650.0f;
currentRect.size.height = 295.0f;
[modalView.view setFrame:currentRect];
[modalView.view removeFromSuperview];
}];
[self.view addSubview:_pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
This works fine for first time button click. When I'm pressing the button again and again this is not animating anymore. It's animating for the first time only. Is there any way to do so?
Thanks in Advance!
The cause is that modalView.view's frame initially if different from
currentRect.origin.y = 650.0f;
currentRect.size.height = 295.0f;
so when changes its frame animation is happens.
But next time when you perform button's action modalView.view's current frame and that frame you sets are same. So there is nothing to animate at all.
Also, you should move [modalView.view removeFromSuperview]; from animation block to completion block
[UIView animateWithDuration:1 animations:^{
CGRect currentRect = modalView.view.frame;
currentRect.origin.y = 650.0f;
currentRect.size.height = 295.0f;
[modalView.view setFrame:currentRect];}
completion:^(BOOL finished) {
[modalView.view removeFromSuperview];
}];
I implemented this method to make flash button, but doing the touch of the button stops working well.
-(void)imageAnimation:(UIButton *)imagen{
[UIView animateWithDuration:.5 animations:^{
imagen.alpha = 1.0;
} completion:^(BOOL finished){
[UIView animateWithDuration:.5 delay:0.5 options:0 animations:^{
imagen.alpha = 0.0;
} completion:^(BOOL finished){
[self imageAnimation:imagen];
}];
}];
}
You know as I can do to make the image flickers button but the button always is active and visible touch that works well?
How about animating a UIImageView's alpha and using a transparent UIButton over it? Alternatively, you could use a UITapGestureRecognizer on the UIImageView itself, though I think the alpha=0 issue will reoccur in this scenario as well.
I am using the following to make a UIImageView slide a little bit forward, and then slide back farther for a parallax scrolling effect.
Code:
[UIView animateWithDuration:0.2f animations:^{
spendrBckGrnd.frame = CGRectMake(spendrBckGrnd.frame.origin.x + 20, 0, spendrBckGrnd.frame.size.width, spendrBckGrnd.frame.size.height);
}];
[UIView animateWithDuration:0.4f animations:^{
spendrBckGrnd.frame = CGRectMake(spendrBckGrnd.frame.origin.x - 80, 0, spendrBckGrnd.frame.size.width, spendrBckGrnd.frame.size.height);
}];
I am wondering how I might go about applying some easing into the animation, right now if just abruptly slides back and forth quickly. I would like to ease into and out of the sliding animations.
You need to do the second animation block after the first one completes.
[UIView animateWithDuration:0.2f animations:^{
spendrBckGrnd.frame = CGRectMake(spendrBckGrnd.frame.origin.x + 20, 0, spendrBckGrnd.frame.size.width, spendrBckGrnd.frame.size.height);
} completion:^{
[UIView animateWithDuration:0.2f animations:^(BOOL finished){
spendrBckGrnd.frame = CGRectMake(spendrBckGrnd.frame.origin.x - 80, 0, spendrBckGrnd.frame.size.width, spendrBckGrnd.frame.size.height);
}];
}];
This will do the trick:
[UIView animateWithDuration:0.2f delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^(void){
//do your animations
} completion:^(BOOL finished){
}];
Check out this tutorial on UIView animation
http://mobile.tutsplus.com/tutorials/iphone/ios-sdk_uiview-animations/
UIView has a method
// [UIView animateWithDuration:(NSTimeInterval) delay:(NSTimeInterval) options:(UIViewAnimationOptions)animations:^(void)animations completion:^(BOOL finished)completion];
typedef enum {
UIViewAnimationCurveEaseInOut, // slow at beginning and end
UIViewAnimationCurveEaseIn, // slow at beginning
UIViewAnimationCurveEaseOut, // slow at end
UIViewAnimationCurveLinear
}
[UIView animateWithDuration:0.6f
delay:0.1f
options:UIViewAnimationCurveEaseInOut
animations:^{
[starView setCenter:CGPointMake(0, 0)];
[starView setAlpha:0.0f];
}
completion:^(BOOL finished){
[starView removeFromSuperview];
points++;
}
];
Also check out this control on github that creates a parallax effect using a custom container view, much like the top view of Path's timeline.
https://github.com/modocache/MDCParallaxView