ios : Nullpointer exception - ios

I got the following code:
- (void) hide_waiting_activity
{
[UIView beginAnimations:nil context:NULL]; {
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:.5];
self.waiting_view.alpha = 0;
self.waiting_label.alpha = 0;
self.activity_indicator.alpha = 0;
} [UIView commitAnimations];
}
The problem: It crashes sometimes and sometimes not. If it crashes the console output looks something like this:
2013-02-07 18:16:21.658 driver[5912:907]
-[NSISRestrictedToNonNegativeVariable count]: unrecognized selector sent to instance 0x1dd3aea0 2013-02-07 18:16:21.679 driver[5912:907]
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[NSISRestrictedToNonNegativeVariable count]: unrecognized selector
sent to instance 0x1dd3aea0'
* First throw call stack: (0x342e03e7 0x3bfd1963 0x342e3f31 0x342e264d 0x3423a208 0x34c90d5b 0x34c9a6c3 0x34c9a56f 0x34c9a781
0x34c9acf1 0x34c99d6b 0x34c9ac31 0x34c92393 0x34c94f01 0x34c95ed7
0x34c9ecab 0x36527519 0x36527689 0x365277ab 0x3652791f 0x36527acf
0x34c95997 0x36527a41 0x3652aad1 0x3652d0d9 0x3652cfe3 0x34226acd
0x3652cf97 0x34226acd 0x3652cf97 0x34226acd 0x3652cf97 0x34226acd
0x3652cf97 0x34226acd 0x3652cf97 0x34226acd 0x3652cf97 0x34226acd
0x3652cf97 0x34226acd 0x3652cf97 0x34c95997 0x36526f3d 0x361623dd
0x35e9e513 0x35e9e0b5 0x35e9efd9 0x35e9e9c3 0x35e9e7d5 0x35e9e639
0x342b5941 0x342b3c39 0x342b3f93 0x3422723d 0x342270c9 0x37e0533b
0x361432b9 0xd3871 0xc29d8) libc++abi.dylib: terminate called throwing
an exception
the corresponding stacktrace looks like this:
or something like this:
driver(5930,0x3df85b78) malloc: * error for object 0x1e565990:
pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug (lldb)
Then the stacktrace looks like
I'm completely clueless. Has anybody got an idea? I'm using ios 6.1.
Update:
Commenting the inner nested brackets does not change anything:
[UIView beginAnimations:nil context:NULL]; {
//[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
//[UIView setAnimationDuration:.5];
self.waiting_view.alpha = 0;
self.waiting_label.alpha = 0;
self.activity_indicator.alpha = 0;
} [UIView commitAnimations];
Update 2:
After removing the curly brackets the app still crashes as decribed.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:.5];
self.waiting_view.alpha = 0;
self.waiting_label.alpha = 0;
self.activity_indicator.alpha = 0;
[UIView commitAnimations];
Update 3:
This is the complete code that contain any of the affected ui elements in the hide_waiting_activity:
MainNavigationController.h
//Waiting overlay
#property (nonatomic,strong) UIActivityIndicatorView* activity_indicator;
#property (nonatomic,strong) UIImageView* waiting_view;
#property (nonatomic,strong) UILabel* waiting_label;
MainNavigationController.m
#implementation MainNavigationController
#synthesize activity_indicator;
#synthesize waiting_view;
#synthesize waiting_label;
...
- (void)viewDidLoad
{
[super viewDidLoad];
//Create a transparent waiting indicator view that is shown to the user while the app is working in background
waiting_view = [[UIImageView alloc] initWithFrame:CGRectMake( 0, 64.f /* top navigation bar is 64.f */, 320, 480 )];
[waiting_view setImage:[UIImage imageNamed:#"Main_Menu_Background.png"]];
waiting_view.backgroundColor = [UIColor clearColor];
self.activity_indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[self.activity_indicator setColor:[UIColor blackColor]];
[self.activity_indicator startAnimating];
self.activity_indicator.center = CGPointMake( 160.f, (240.f-64.f) );
[waiting_view addSubview:activity_indicator];
waiting_label = [[UILabel alloc] initWithFrame:CGRectMake( 110.f, (240.f-64.f)+30.f, 100.f, 16.f)];
waiting_label.font = [UIFont boldSystemFontOfSize:13.f];
waiting_label.textColor = [UIColor blackColor];
waiting_label.backgroundColor = [UIColor clearColor];
waiting_label.textAlignment = UITextAlignmentCenter;
waiting_label.text = NSLocalizedString(#"Please_Wait_Text", #"");
[waiting_view addSubview:waiting_label];
[self.view addSubview:waiting_view];
[self.view bringSubviewToFront:self.activity_indicator];
self.waiting_view.hidden = YES;
self.activity_indicator.hidden = YES;
...
}
- (void) show_waiting_activity
{
if( self.waiting_view.alpha == 1 && self.waiting_view.hidden == NO )
return;
self.waiting_view.hidden = NO;
self.activity_indicator.hidden = NO;
[UIView beginAnimations:nil context:NULL]; {
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:.2];
self.waiting_view.alpha = 1;
self.waiting_label.alpha = 1;
self.activity_indicator.alpha = 1;
} [UIView commitAnimations];
}
- (void) hide_waiting_activity
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:.5];
self.waiting_view.alpha = 0;
self.waiting_label.alpha = 0;
self.activity_indicator.alpha = 0;
[UIView commitAnimations];
}
I'm asking myself where in this code the ui elements could be destroyed in these .5 seconds?

The problem isn't in the code you pasted - the problem is what's happening to the views it's referencing after the animation starts (somewhere else in your code). If the animation is running for 0.5 seconds, all those views must be alive still for the next 0.5 seconds.
So, your choices for views that are not living long enough: self, self.waiting_view, self.waiting_label, self.activity_indicator.

Related

Fade In / Fade out 2 Labels infinite loop inside tableview

I'm trying to show an intermittent label with two changing strings (like a banner) in an infinite loop.
The first label should fade in. After that it should fade out and let a second label do the same. Then repeat the sequence infinitely or a long time.
The label is inside a subclass of a UITableView.
I tried this so far:
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
// Inside a cell an at its own section of the tableview
cell.label1.alpha = 1;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:3];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationRepeatCount:INFINITY];
[cell.label1 setAlpha:0];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView commitAnimations];
cell.label2.alpha = 1;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:3];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationRepeatCount:INFINITY];
[cell.label1 setAlpha:0];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView commitAnimations];
...
}
This code works fine but the effect is not clear because the fade in label1 is crossing fade out label2 and it is weird.
So, how can I make a break between the two animations, to see the fading labels clearly?
Thanks #Paulw11 for your answer, now it works fine, here is my code with the changes:
cell.label2.alpha = 0;
cell.label1.alpha = 1;
[UIView animateKeyframesWithDuration:15 delay:0.0 options:0 animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.25 animations:^{
cell.label1.alpha = 0;
cell.label2.alpha = 0;
[self.view layoutIfNeeded];
}];
[UIView addKeyframeWithRelativeStartTime:0.25 relativeDuration:0.25 animations:^{
cell.label1.alpha = 0;
cell.label2.alpha = 1;
[self.view layoutIfNeeded];
}];
[UIView addKeyframeWithRelativeStartTime:0.50 relativeDuration:0.25 animations:^{
cell.label1.alpha = 0;
cell.label2.alpha = 0;
[self.view layoutIfNeeded];
}];
[UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.25 animations:^{
cell.label1.alpha = 1;
cell.label2.alpha = 0;
[self.view layoutIfNeeded];
}];
[UIView setAnimationRepeatCount: 200];
} completion:nil];

-[TPKeyboardAvoidingScrollView keyboardWillHide:]: message sent to deallocated instance in ios?

Imported TPKeyboardAvoidingScrollView.h and .m files in my xcode projects and used that TPkeyboard for my UIScrollview in all classes of my project like this
TPKeyboardAvoidingScrollView *scrollView = [[TPKeyboardAvoidingScrollView alloc] init];
The app is terminating and showing the error as
-[TPKeyboardAvoidingScrollView keyboardWillHide:]: message sent to deallocated
instance.
Can anyone please provide me some information.
Thanks in advance.
KeyboardWillHide function in TPKeyboardAvoidingScrollView.m:
- (void)keyboardWillHide:(NSNotification*)notification {
_keyboardRect = CGRectZero;
_keyboardVisible = NO;
// Restore dimensions to prior size
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
[UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
self.contentInset = _priorInset;
self.contentOffset = CGPointMake(self.contentOffset.x, 0);
[self setScrollIndicatorInsets:self.contentInset];
_priorInsetSaved = NO;
[UIView commitAnimations];
}

How to hide an item after fading it out (Objective-C)

I have the following if statement,
if (CGRectIntersectsRect(car.frame, car2.frame) && (upMovement = -1 ) && (car2.hidden == NO)){
[self bounce];
[self carexplode];
if (car2used == NO) {
addedScore = 1;
car2Used = YES;
}
car2.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"car2flames.png"], nil];
[car2 setAnimationRepeatCount:0];
car2.animationDuration = 20;
[car2 startAnimating];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:4];
[iceblock6 setAlpha:0];
[UIView commitAnimations];
car2.hidden = YES;
Essentially, I want it to execute the top part of the method if one car crashes into it, then using UIView animations ^^, I want it to fade out, then be hidden, so that I can set hidden to no again when it reenters the view (after it exits the screen it reloads to the top of the screen). But with this, it just automatically is hidden, without the 4 second fade out animation. How can I fix this? I've tried putting car2.hidden in an if statement, but I don't know what to put in the condition because UIView isn't really bools or integers and all that. Anyone have any advice?
[UIView animateWithDuration:1.0 delay:0.0 options:(UIViewAnimationOptions) animations:^{
//place your animation here
[iceblock6 setAlpha:0];
} completion:^(BOOL finished) {
//called when animation did finish. do what you want
car2.hidden = YES;
}];
Other way:
{
...
if (CGRectIntersectsRect(car.frame, car2.frame) && (upMovement = -1 ) && (car2.hidden == NO)){
[self bounce];
[self carexplode];
if (car2used == NO) {
addedScore = 1;
car2Used = YES;
}
car2.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"car2flames.png"], nil];
[car2 setAnimationRepeatCount:0];
car2.animationDuration = 20;
[car2 startAnimating];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:4.0];
[iceblock6 setAlpha:0];
[UIView commitAnimations];
[self performSelector:#selector(hideCar2) withObject:self afterDelay:4.0];
}
-(void)hideCar2
{
car2.hidden = YES;
}

View animation issue

I'm trying to flip animate a view into another view, which corresponds of a small section of the screen. Both views have the same dimensions and center.
I keep getting as a result the animation of the full screen. From the code below, can somebody please let me know what the heck i'm doing wrong?
Thank you,
-j
+ (void) flipView:(UIView*)viewA toView:(UIView*)viewB wait:(Boolean)wait
{
// get parent view
UIView *parent = [viewA superview];
CGRect r = viewA.frame;
// create container view with the same dimensions as ViewA
UIView *containerView = [[UIView alloc] initWithFrame:viewA.bounds];
containerView.center = viewA.center;
// attache both views to intermidiate view
[containerView addSubview:viewA];
[containerView addSubview:viewB];
[viewA removeFromSuperview];
[parent addSubview:containerView];
viewB.alpha = 0;
viewA.alpha = 1;
// Perform the annimation
__block BOOL done = NO;
[UIView transitionWithView:viewA
duration:2.0
options: (UIViewAnimationOptionTransitionFlipFromTop)
animations:^{
viewA.alpha = 0;
viewB.alpha = 1; }
completion:^(BOOL finished) {
done = YES;
// detach all views
[viewA removeFromSuperview];
[viewB removeFromSuperview];
[containerView removeFromSuperview];
}
];
if(wait) {
while (done == NO)
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
First get rid of the old animation code (or at least commit it), it should look like this:
+ (void) flipView:(UIView*)viewA toView:(UIView*)viewB wait:(BOOL)wait
{
viewB.alpha = 0;
viewA.alpha = 1;
__block BOOL done = NO;
[UIView transitionWithView:viewA
duration:2.0
options: (UIViewAnimationOptionTransitionFlipFromTop)
animations:^{
viewA.alpha = 0;
viewB.alpha = 1; }
completion:^(BOOL finished) {
done = YES;
}
];
if(wait) {
while (!done)
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
Second, the superview of the subview that you want to transition is actually going to get the transition. So this means that you'll have to add viewA and viewB to a subview, add this subview to another view and then do the animation.
Here is a solution without any hacks with runloop. Just use the first message to run a transition to another view, and the second message to return to original state:
- (void) forwardTransitionFromView: (UIView *) viewA toView: (UIView *) viewB
{
NSAssert(viewA.superview, #"The 'from' view should be added to a view hierarchy before transition");
NSAssert(!viewB.superview, #"The 'to' view should NOT be added to a view hierarchy before transition");
CGSize viewASize = viewA.bounds.size;
viewB.frame = CGRectMake(0.0, 0.0, viewASize.width, viewASize.height);
[UIView transitionWithView:viewA
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[viewA addSubview:viewB];
}
completion:NULL];
}
- (void) backwardTransitionFromView: (UIView *) viewB toView: (UIView *) viewA
{
NSAssert([viewB.superview isEqual:viewA], #"The 'from' view should be a subview of 'to' view");
[UIView transitionWithView:viewA
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[viewB removeFromSuperview];
}
completion:NULL];
}
Why dont you flip both views in same direction?
-(void) FlipView:(bool) fromRight {
if(fromRight) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:view1 cache:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:view2 cache:YES];
[UIView commitAnimations];
}
else {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view1 cache:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view2 cache:YES];
[UIView commitAnimations];
}
}
and call the method like below:
[view1 setHidden:NO];
[self FlipView:YES];
[view2 setHidden:YES];
to reverse the animation:
[view2 setHidden:NO];
[self FlipView:NO];
[view1 setHidden:YES];

UiViewAnimation not call setAnimationDidStopSelector

I created this animation and I entered through the stop animation
[UIView setAnimationDidStopSelector:#selector (TermineAnimazioneGoPointAssignedWithDelay)] ;
When the animation part of the SetAnimationDidStop is not called ... Can you tell me why and where am I doing wrong ?
This is all the way animation :
-(void)setViewStatusGoPointassigned {
ViewgoPointAssignMessage = [[UIView alloc] initWithFrame:CGRectMake(115, 150, 100, 100) ];
ViewgoPointAssignMessage.backgroundColor = [UIColor colorWithRed:(77/255.0) green:(108/255.0) blue:(143/255.0) alpha:(1)];
[ViewgoPointAssignMessage.layer setCornerRadius:10.0f];
[ViewgoPointAssignMessage.layer setMasksToBounds:YES];
[UIView animateWithDuration:0.2 animations:^{
ViewgoPointAssignMessage.transform = CGAffineTransformMakeScale(1.05, 1.05);
ViewgoPointAssignMessage.alpha = 0.8; }
completion:^(BOOL finished){
[UIView animateWithDuration:2/15.0 animations:^{
ViewgoPointAssignMessage.transform = CGAffineTransformMakeScale(0.9, 0.9);
ViewgoPointAssignMessage.alpha = 0.9; }
completion:^(BOOL finished) {
[UIView animateWithDuration:1/7.5 animations:^{
ViewgoPointAssignMessage.transform = CGAffineTransformIdentity;
ViewgoPointAssignMessage.alpha = 1.0; } ];
} ];
} ];
[self.view addSubview:ViewgoPointAssignMessage];
[UIView setAnimationDidStopSelector:#selector(TermineAnimazioneGoPointAssignedWithDelay)];
}
-(void)TermineAnimazioneGoPointAssignedWithDelay {
[self performSelector:#selector(EliminazioneViewAfterDelay) withObject:self afterDelay:0.01];
}
-(void)EliminazioneViewAfterDelay {
CGRect endREct;
endREct = CGRectMake(350 , 0 , 330, 90);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.005];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(EliminaAnimazione)];
ViewgoPointAssignMessage.frame = endREct;
[UIView commitAnimations];
}
- (void)EliminaAnimazione {
[ViewgoPointAssignMessage removeFromSuperview];
}
First of all, to answer your question.
You may try
[UIView animateWithDuration:(NSTimeInterval)duration animations:^(void)animations completion:^(BOOL finished)completion]
and call [self TermineAnimazioneGoPointAssignedWithDelay] in the completion.
Secondly, [UIView setAnimationDidStopSelector:#selector(TermineAnimazioneGoPointAssignedWithDelay)] doesn't work because according to the reference, setAnimationDidStopSelector must be called between calls to the beginAnimations:context: and commitAnimations methods. Since your code doesn't comply to this rule, the function does not work either.
Hopefully it explains! Good Luck!

Resources