Nested animation block caused "Segmentation fault" - iphone

I try to show three images, one after one, with the following code:
image_1.alpha = 0.0;
image_2.alpha = 0.0;
image_3.alpha = 0.0;
[UIView animateWithDuration:0.25
animations:^{
image_1.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.25
animations:^{
image_2.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.25
animations:^{
image_3.alpha = 1.0;
} completion:^(BOOL finished) {
;
}];
}];
}];
gives: internal compiler error: Segmentation fault
There is no error if the nesting contains two animation blocks. Is nested animation block no allowed or comes with some limitation?

Related

Repeat Fade In / Fade Out effects to switch between three views

I've created one view containing three subviews.
I would like to fade in / out the three subviews and repeat the effect indefinitely.
I try something like :
+ (void)fadeIn:(UIView *)view withDuration:(float)duration
{
[UIView animateWithDuration:duration animations:^{
view.alpha = 1.0;
}];
}
+ (void)fadeOut:(UIView *)view withDuration:(float)duration
{
[UIView animateWithDuration:duration animations:^{
view.alpha = 0.0;
}];
}
[UIView animateWithDuration:5.0
delay:2.0
options:UIViewAnimationCurveLinear | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^
{
[Utilities fadeOut:headSubtitle_1 withDuration:1];
[Utilities fadeIn:headSubtitle_2 withDuration:1];
[Utilities fadeOut:headSubtitle_2 withDuration:1];
[Utilities fadeIn:headSubtitle_3 withDuration:1];
[Utilities fadeOut:headSubtitle_3 withDuration:1];
[Utilities fadeIn:headSubtitle_1 withDuration:1];
}
completion:^(BOOL finished)
{}];
But it doesn't work well.
The effect that I would obtain is :
Display headSubtitle_1 for 2 seconds
FadeOut headSubtitle_1 in 1 second
FadeIn headSubstitle_2 in 1 second
Display headSubstitle_2 for 2 seconds
FadeOut headSubtitle_2 in 1 second
FadeIn headSubstitle_3 in 1 second
Display headSubstitle_3 for 2 seconds
FadeOut headSubtitle_3 in 1 second
FadeIn headSubtitle_1 in 1 second
Repeat to 1.
Thanks a lot !
EDIT
Finally, I try something like this :
+ (void)runAnimationSubtitleOrdersWithSub1:(UITextView *)headSubtitle_1 andSub2:(UITextView *)headSubtitle_2 andSub3:(UITextView *)headSubtitle_3
{
[UIView animateWithDuration:1.0 delay:1.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
headSubtitle_1.alpha = 0;
} completion:^(BOOL finished) {
if (finished)
{
[UIView animateWithDuration:1.0 delay:1.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
headSubtitle_2.alpha = 1;
} completion:^(BOOL finished) {
if (finished)
{
[UIView animateWithDuration:1.0 delay:1.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
headSubtitle_2.alpha = 0;
} completion:^(BOOL finished) {
if (finished)
{
[UIView animateWithDuration:1.0 delay:1.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
headSubtitle_3.alpha = 1;
} completion:^(BOOL finished) {
if (finished)
{
[UIView animateWithDuration:1.0 delay:1.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
headSubtitle_3.alpha = 0;
} completion:^(BOOL finished) {
if (finished)
{
[UIView animateWithDuration:1.0 delay:1.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
headSubtitle_1.alpha = 1;
} completion:^(BOOL finished) {
[FormBuilder runAnimationSubtitleOrdersWithSub1:headSubtitle_1 andSub2:headSubtitle_2 andSub3:headSubtitle_3];
}];
}
}];
}
}];
}
}];
}
}];
}
}];
}
It's really ugly ! If some body knows a better way to do this.
Maybe you can play with several animation with something like this (but, it's not beautiful) :
_imageView.alpha = 0.0f;
_imageView2.alpha = 0.0f;
_imageView3.alpha = 0.0f;
[UIView animateWithDuration:1
delay:0
options:UIViewAnimationCurveLinear | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^{
_imageView.alpha = 1.0f;
[UIView animateWithDuration:1
delay:1
options:UIViewAnimationCurveLinear | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^{
_imageView2.alpha = 1.0f;
} completion:^(BOOL finished) {
_imageView2.alpha = 0.0f;
}
];
} completion:^(BOOL finished) {
_imageView.alpha = 0.0f;
}
];
Take a look at [UIView beginAnimations:(NSString *) context:(void *)].

Custom UIView doesn't get removed from superview when loaded again while animating

The question explains it all actually.
I load a custom UIView on top of my current view, animated, using this code:
- (void)showView
{
self.blurView.alpha = 0.f;
[UIView animateWithDuration:2.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^
{
self.blurView.alpha = 1.f;
} completion:^(BOOL finished) {
[UIView animateWithDuration:2.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^
{
self.blurView.alpha = 0.f;
} completion:nil];
}];
}
It works, but when I perform -(void)showView again while it is still animating, the custom view doesn't get removed from the screen.
It just stays like this:
I figured out what the problem was.
blurView is a public variable and every time I did -(void)showView it used the same variable, setting the alpha to 0.f just once, thus never changing the alpha of the first show.
I declared the variable blurView in the method itself and now it works because every blurView gets it's own pointer.
-(void)someMethod
{
//Create a live blur view
FXBlurView *blurView = [[FXBlurView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
blurView.center = CGPointMake(self.view.window.frame.size.width / 2, self.view.window.frame.size.height / 2);
blurView.layer.cornerRadius = 20.f;
[self.view.window addSubview:blurView];
[self showView:(blurView)];
}
- (void)showView:(FXBlurView *)blurView
{
//Make full transparent before showing
blurView.alpha = 0.f;
//Start animation
[FXBlurView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^
{
blurView.alpha = 1.f;
} completion:^(BOOL finished) {
if (finished)
{
//End animation
[FXBlurView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^
{
blurView.alpha = 0.f;
} completion:nil];
}
}];
}
You should add to the top of your function this line:
[self.view.layer removeAllAnimations];
It will remove all of the active animations.
It doesn't work because you have implemented a delay, use animation block with delay - it will create animation keys that could be removed with this function above.
[UIView animateWithDuration:0.3 delay:0.0
options:UIViewAnimationOptionAllowUserInteraction
animations:^
{
// ...
} completion:NULL];

delay in getting complete boolean callback of UIView block animation (animateWithDuration)

i am doing block animation, my project is using opengl for gameplay and uiview for menu like stuff.
i am animating uiview using animateWithDuration method, bt facing issue at getting delay complete animation boolean callback. I tried the same code in UIKit app and it works very smoothly.
Below is my code:
-(void) playAnimation:(UIButton *)_button atPosition:(CGRect)_rect withDuration:(CGFloat)_duration andDelay:(CGFloat)_delay andDiection:(NSInteger)_direction
{
[UIView animateWithDuration:_duration
delay:_delay
options:UIViewAnimationCurveLinear
animations:^{
_button.frame = _rect;
}
completion:^(BOOL finished){
[UIView animateWithDuration:0.1
delay:0.0
options:UIViewAnimationCurveEaseInOut
animations:^{
CGRect rect = _rect;
rect.origin.x = _rect.origin.x + (10 * _direction);
_button.frame = rect;
}
completion:^(BOOL finished){
[UIView animateWithDuration:0.1
delay:0.0
options:UIViewAnimationCurveEaseInOut
animations:^{
_button.frame = _rect;
}
completion:^(BOOL finished){
}];
}];
}];
}

How to scale UIImageView properly with UIView animateWithDuration?

I'm scaling UIImageView and then reverting it using UIView animateWithDuration with UIViewAnimationOptionAutoreverse option. The problem is the image animation is a little bit jaggy (twitching) at the end of the animation. Here's my code:
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionAutoreverse
animations:^{
myImage.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);}
completion:^(BOOL finished){if (finished){
myImage.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);}}];
I know that I'm missing something but don't know where to start :(
UPDATE1: I'm performing nested 6 animations where each next animation performs after previous one. For that I'm using block animations and performing each next animation in complete block.
UPDATE2: I have tried with UIViewAnimationOptionRepeat option but there's still some flash effect after each scale animation.
UIViewAnimationOptionAutoreverse does nothing without also using the UIViewAnimationOptionRepeat option. Your animation as written will shrink the image to 90%, then snap back to 100% in the completion block. Maybe you can follow this animation with another that scales back to 100% over a quarter second. Something like this:
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseInOut
animations:^{
myImage.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);}
completion:^(BOOL finished){if (finished){
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseInOut
animations:^{
myImage.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);}
completion:NULL];}}];
.h file declerd.
NSInteger imgint;
.m file in code and try.
-(void)
{
[NSTimer scheduledTimerWithTimeInterval:(0.85f)target:self selector:#selector(play_btn_animation) userInfo:nil repeats:YES];
}
-(void)play_btn_animation
{
if(imgint == 0)
{
[UIView animateWithDuration:0.8
delay:0.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
img.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.8, 0.8);
}
completion:^(BOOL finished) {
img = 1;
}];
}
else
{
[UIView animateWithDuration:0.8
delay:0.0
options: UIViewAnimationOptionCurveEaseOut
animations:^{
img.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 1);
}
completion:^(BOOL finished) {
imgint = 0;
}];
}
}

internal compiler error: Bus error

I have the following code (see below) and if I compile it as is i get "internal compiler error: Bus error". If I comment out the last ImageOne.transform, everything works fine. If the file ends in .m it compiles fine if I change it to .mm then it has an issue. Any ideas?
[UIView animateWithDuration:duration1 delay:delay options:UIViewAnimationCurveEaseIn animations:^{
ImageOne.transform = CGAffineTransformMakeScale(scale1, scale1);
ImageOne.alpha = 1.0f;
}
completion:^(BOOL finished){
[UIView animateWithDuration:SecondDuration delay:SecondDelay options:UIViewAnimationCurveEaseOut animations:^{
ImageOne.transform = CGAffineTransformMakeScale(scale2, scale2);
}
completion:^(BOOL finished){
[UIView animateWithDuration:SecondDuration delay:SecondDelay options:UIViewAnimationCurveEaseOut animations:^{
ImageOne.transform = CGAffineTransformMakeScale(scale1, scale1); //results in bus error, i think its due to nesting
}
completion:nil];
}];
}];
}
Why do you nest another block, rather than just adding
ImageOne.transform = CGAffineTransformMakeScale(scale1, scale1);
into the first block like so
completion:^(BOOL finished)
{
[UIView animateWithDuration:SecondDuration delay:SecondDelay options:UIViewAnimationCurveEaseOut animations:^{
ImageOne.transform = CGAffineTransformMakeScale(scale1, scale1);
ImageOne.transform = CGAffineTransformMakeScale(scale2, scale2);
Hope this helps. :)