PDA

View Full Version : Jerky Animation?




ArtOfWarfare
Dec 10, 2009, 10:25 PM
I have a button that creates a subclass of a UIAlertView. The first time I run it, the animation is very jerky. The second, third, etc. times I use it, it's nice and smooth.

I was curious, how can I remedy the jerkiness from the first time it opens?

Here's the methods (the first UIAlertView loads fine every time, it's the subclass one in the else statements that's an issue.)
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
quickAddController = [[QuickAddController alloc] initWithTitle:@"Add Assignment" message:@"\n" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Add", nil];
quickAddController.classes = classes;
quickAddController.mostRecentClass = mostRecentClass;
[quickAddController reflectMostRecentClass];
[quickAddController show];
[quickAddController release];
}

And here's the quickAddController init method...

- (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...
{
if (self = [super initWithTitle:@"Add Assignment" message:@" \n \n \n " delegate:(id)delegate cancelButtonTitle:@"Cancel" otherButtonTitles:@"Add", nil])
{
// New Assignment Name
addAssignmentName = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 55.0, 260.0, 31.0)];
addAssignmentName.borderStyle = UITextBorderStyleRoundedRect;
addAssignmentName.autocapitalizationType = UITextAutocapitalizationTypeWords;
addAssignmentName.autocorrectionType = UITextAutocorrectionTypeNo;
addAssignmentName.placeholder = @"New Assignment Name";
[self addSubview:addAssignmentName];
[addAssignmentName addTarget:self action:@selector(selectName:) forControlEvents:UIControlEventTouchDown];
[addAssignmentName becomeFirstResponder];
[addAssignmentName release];

// New Assignment Class Name
addAssignmentClass = [UIButton buttonWithType:UIButtonTypeRoundedRect];
addAssignmentClass.frame = CGRectMake(12.0, 94.0, 126.0, 37.0);
addAssignmentClass.backgroundColor = [UIColor clearColor];
addAssignmentClass.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
addAssignmentClass.titleLabel.adjustsFontSizeToFitWidth = YES;
addAssignmentClass.titleLabel.minimumFontSize = 10.0;
[addAssignmentClass addTarget:self action:@selector(selectClass:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:addAssignmentClass];

// New Assignment Due Date
addAssignmentDueDate = [UIButton buttonWithType:UIButtonTypeRoundedRect];
addAssignmentDueDate.frame = CGRectMake(146.0, 94.0, 126.0, 37.0);
[addAssignmentDueDate setTitle:@"Select Date Due" forState:UIControlStateNormal];
addAssignmentDueDate.backgroundColor = [UIColor clearColor];
[addAssignmentDueDate addTarget:self action:@selector(selectDate:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:addAssignmentDueDate];

[self setTransform:CGAffineTransformMakeTranslation(0.0, 85.0)];
}
return self;
}

Suggestions?



ArtOfWarfare
Dec 12, 2009, 11:32 PM
I decided to stick several NSLog messages in my code and I found, very much to my surprise, that my App isn't spending most of it's time initializing the custom Alert View.

Here's the code, along with the times the NSLogs were posted at.

NSLog(@"Send Init");
quickAddController = [[QuickAddController alloc] initWithTitle:@"Add Assignment" message:@"\n" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Add", nil];
quickAddController.classes = classes;
quickAddController.mostRecentClass = mostRecentClass;
NSLog(@"Send Show");
[quickAddController show];
[quickAddController finishDrawing];
[quickAddController release];

NSLog(@"Start Init");
[... lots of init code omitted here...]
NSLog(@"Finish Init");
return self;

NSLog(@"Start Show");
[super show];
NSLog(@"End Show");

(Nothing has been ommitted from show. Seriously, the only reason I wrote it was to see how long it takes to go from start to finish showing.)

The first time I hit the button...
2009-12-13 00:15:29.654 ClassNotes[3530:207] Send Init
2009-12-13 00:15:29.667 ClassNotes[3530:207] Start Init
2009-12-13 00:15:29.966 ClassNotes[3530:207] Finish Init
2009-12-13 00:15:29.973 ClassNotes[3530:207] Send Show
2009-12-13 00:15:29.977 ClassNotes[3530:207] Start Show
2009-12-13 00:15:30.475 ClassNotes[3530:207] End Show

It spent just about 0.3 seconds on initializing and then another 0.5 seconds on showing. Altogether 0.8 seconds

Then I hit the button again...
2009-12-13 00:15:38.149 ClassNotes[3530:207] Send Init
2009-12-13 00:15:38.152 ClassNotes[3530:207] Start Init
2009-12-13 00:15:38.170 ClassNotes[3530:207] Finish Init
2009-12-13 00:15:38.172 ClassNotes[3530:207] Send Show
2009-12-13 00:15:38.174 ClassNotes[3530:207] Start Show
2009-12-13 00:15:38.204 ClassNotes[3530:207] End Show

It spends about 0.02 seconds on initializing and then another 0.03 seconds to show. Altogether about 0.05 seconds, or just 1/16th of the time it takes the first time.

I tried several different approaches involving threads, but my code just doesn't seem to be very thread safe :-/

And then it hit me...

To the very start of my code I added this extra bit:

quickAddController = [[QuickAddController alloc] initWithTitle:@"Add Assignment" message:@"\n" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Add", nil];
quickAddController.classes = classes;
quickAddController.mostRecentClass = mostRecentClass;
quickAddController.hidden = YES;
[quickAddController show];
[quickAddController finishDrawing];
[quickAddController dismissWithClickedButtonIndex:0 animated:YES];
[quickAddController release];

And so now, every time the button gets hit my application has already prepped itself to display it.

If no one has a better suggestion, I think I'll stay with this method.