internal compiler error: Bus error - iphone

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. :)

Related

UIView Animation Block Makes No Changes

The following code is sheer simple. _facebookF is a UIImageView.
if (animationOn == YES) {
[UIView animateWithDuration:0.4 animations:^{
[_faceBookF setAlpha:0];
}];
[_faceBookF setImage:[UIImage imageNamed:#"facebookFBlue.png"]];
[UIView animateWithDuration:0.4 animations:^{
[_faceBookF setAlpha:1];
}];
} else {
[UIView animateWithDuration:0.4 animations:^{
[_faceBookF setAlpha:0];
}];
[_faceBookF setImage:[UIImage imageNamed:#"facebookF.png"]];
[UIView animateWithDuration:0.4 animations:^{
[_faceBookF setAlpha:1];
}];
}
The app gets to the method which contains this code fine, but no changes to the UI occur throughout the entire block of code. To my knowledge, the app is running on the main thread.
Any guesses?
UPDATE--In fact, the issue is that the image is not being changed at all--with or without the animation. Both images are accessed fine in other parts of the app.
It looks like you are trying to run sequential animations, but the way you have coded them, they are likely to run in parallel. What you need to do is this:
if (animationOn == YES) {
[UIView animateWithDuration:0.4 animations:^{
[_faceBookF setAlpha:0];
} completion:^(BOOL finished) {
[_faceBookF setImage:[UIImage imageNamed:#"facebookFBlue.png"]];
[UIView animateWithDuration:0.4 animations:^{
[_faceBookF setAlpha:1];
}];
}];
}
else {
[UIView animateWithDuration:0.4 animations:^{
[_faceBookF setAlpha:0];
}completion:^(BOOL finished) {
[_faceBookF setImage:[UIImage imageNamed:#"facebookF.png"]];
[UIView animateWithDuration:0.4 animations:^{
[_faceBookF setAlpha:1];
}];
}];
}
Try this. This starts the second animation after the first has completed. So it will fade out the UIImageView and then fade it up with different version of the image.
[UIView animateWithDuration: 0.4
animations:^
{
[_faceBookF setAlpha:0];
}
completion:^(BOOL finished)
{
[_faceBookF setImage:[UIImage imageNamed:#"facebookFBlue.png"]];
[UIView animateWithDuration:0.4
animations:^
{
[_faceBookF setAlpha:1];
}];
}];
Thanks for your responses. I've implemented the completion block you both mentioned to avoid both animations firing at once. However, the main issue had to do with the method not being accessed properly. I can't see exactly why, as the facebookF variable was not nil, and the if and log statements in the method worked fine. Anyway, I have switched to a NSNotification solution, and now all parts of the method are being accessed.

how to stop an already running animation

I am doing some animation using block level technique. I want to stop the animation on the basis of certain condition. How will I stop the animation from completing?
Following is my code for animation:
[UIView animateWithDuration:2.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction
animations:^{
if([arrAns count]>0)
vwb1.center = CGPointMake(260, 40);
}
completion:^(BOOL finished){
[UIView animateWithDuration:1.5 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction
animations:^{
if([arrAns count]>1)
vwb2.center = CGPointMake(260, 100);
}
completion:^(BOOL finished){
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction
animations:^{
if([arrAns count]>2)
vwb3.center = CGPointMake(260, 160);
}
completion:^(BOOL finished){
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction
animations:^{
if([arrAns count]>3)
vwb4.center = CGPointMake(260, 220);
}
completion:^(BOOL finished){
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
if([arrAns count]>4)
vwb5.center = CGPointMake(260, 280);
} completion:nil];
}];
}];
}
];
}];
I am not having any key here so I can nnot remove it on the basis of a key. There is also a feature as removeallanimation but I am not able to use it. If someone could help me on how to use that it will also be fine.
Edit: Ok I figured out how to do it, I am doing it using following code:
[self.view.layer removeAllAnimations];
But now I have problem that my block level animation which have not yet started is still running. So if I remove the animation at second block it still executes remaining block. I need to stop that also.
Thanks
Pankaj
You should check finished variable. And start next animation (inside a block) only if previous was finished (finished == YES), not stopped.
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
...
completion
A block object to be executed when the animation sequence
ends. This block has no return value and takes a single Boolean
argument that indicates whether or not the animations actually
finished before the completion handler was called. If the duration of
the animation is 0, this block is performed at the beginning of the
next run loop cycle.

Why does transition animation not work with block objects, but with deprecated animations API

I'm trying a flip or curl between to views in a container which works pretty well using the following code:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.8];
[UIView setAnimationTransition:animationOption
forView:container cache:YES];
[container addSubview:nuView];
[oldView removeFromSuperview];
[UIView commitAnimations];
but does not with
[UIView transitionWithView:container
duration:.8
options:animationOption
animations:^
{
[container addSubview:nuView];
[oldView removeFromSuperview];
}
completion:^(BOOL finished)
{
}];
Any ideas?
What is animationOption? This code works perfectly well in one of my apps:
[UIView transitionWithView:currentContainerView
duration:0.75
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[currentContainerView.frontView removeFromSuperview];
[currentContainerView addSubview:currentContainerView.flippedSideView];
}
completion:^(BOOL finished) {
// stuff
}];
Check if you are using UIViewAnimationOptionTransition or UIViewAnimationTransition !

Nested animation block caused "Segmentation fault"

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?

UIView iPhone SDK nested animations

I would like to have a nested animation for my view.
I have one animation stop selector which gets called just fine:
[UIView setAnimationDidStopSelector:#selector(growAnimationDidStop1:finished:context:)];
However inside of this selector I want to do more animation and when done yet another selector to be called:
- (void)growAnimationDidStop1:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
...
[UIView setAnimationDidStopSelector:#selector(growAnimationDidStop2:finished:context:)];
...
[UIView commitAnimations];
}
The problem is that growAnimationDidStop2 is never called. Why is this?
You can also do this with blocks, and Apple now recommends this. Consider the following as pseudo-code:
[UIView animateWithDuration:0.3
delay:0.0
options:UIViewAnimationCurveEaseInOut
animations:^{
[self doAnimationOne];
} completion:^(BOOL finished){
[UIView animateWithDuration:0.4
delay:0.0
options:UIViewAnimationCurveEaseInOut
animations:^{
[self doAnimationNine];
}
completion:^(BOOL finished) {
[UIView animateWithDuration:0.3
delay:0.0
options:UIViewAnimationCurveEaseInOut
animations:^{
[self doAnimationFive];
}
completion:^(BOOL finished) {}];
}];
}];
It's also good practice for your animations to be "social", for instance do:
BOOL userInteractionEnabled = [self isUserInteractionEnabled];
[self setUserInteractionEnabled:NO];
BOOL animationsEnabled = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:YES];
before starting your animation, and then in the final completion block do:
[UIView setAnimationsEnabled:animationsEnabled];
[self setUserInteractionEnabled:userInteractionEnabled];
Oops, answered it myself. I had to start a brand new animation context in the first stop method
The best way to do multiple animations in sequence is with a queue of blocks.
See how clean the result is:
NSMutableArray* animationBlocks = [NSMutableArray new];
typedef void(^animationBlock)(BOOL);
// getNextAnimation
// removes the first block in the queue and returns it
animationBlock (^getNextAnimation)() = ^{
animationBlock block = (animationBlock)[animationBlocks firstObject];
if (block){
[animationBlocks removeObjectAtIndex:0];
return block;
}else{
return ^(BOOL finished){};
}
};
//add a block to our queue
[animationBlocks addObject:^(BOOL finished){;
[UIView animateWithDuration:1.0 animations:^{
//...animation code...
} completion: getNextAnimation()];
}];
//add a block to our queue
[animationBlocks addObject:^(BOOL finished){;
[UIView animateWithDuration:1.0 animations:^{
//...animation code...
} completion: getNextAnimation()];
}];
//add a block to our queue
[animationBlocks addObject:^(BOOL finished){;
NSLog(#"Multi-step Animation Complete!");
}];
// execute the first block in the queue
getNextAnimation()(YES);
Taken from: http://xibxor.com/objective-c/uiview-animation-without-nested-hell/