I have a method for saving the contents of a UIScrollView with a user-supplied filename.
Everything works fine, except that there is a long delay when the user taps the "Save" button and the method is called. I can't work out what's calling the delay, nor find a way to indicate to the user that everything is ok, we have not crashed!
I thought the delay was occurring during the renderInContext, but it seems to be happening a lot earlier, when there is not much else going on.
Here is the troublesome method:
- (void)captureViewImage {
NSLog(@"captureViewImage called!");
// long delay happens here!
fileNamer.title = @"Preparing to save...";
// get user's file name
NSString *fileName = fileNamer.fileNameField.text;
// dismiss keyboard
[fileNamer.fileNameField resignFirstResponder];
// dismiss modal view
[self dismissFileNamingFormSheet];
CGRect oldFrame = mainScrollView.frame;
// capture off-screen content
mainScrollView.frame = CGRectMake(0, 0, 1024, 1432);
// make screenshot
UIGraphicsBeginImageContext(mainScrollView.bounds.size);
[mainScrollView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// save screenshot in docs dir
NSData *pngData = UIImagePNGRepresentation(screenImg);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
[pngData writeToFile:[documentsDir stringByAppendingPathComponent:fileName]
options:NSDataWritingAtomic error:nil];
// revert scroll view
mainScrollView.frame = oldFrame;
}
fileNamer is a custom class that throws up a UIModalPresentationFormSheet asking the user to supply a name for the file. It looks like this:
@implementation FileNamingViewController
@synthesize fileNameField, newFileName;
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil parent:(TestDriveViewController *) myParent {
if (self == [super initWithNibName:@"FileNamingViewController" bundle:nil]) {
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]
initWithTitle:@"Save"
style:UIBarButtonItemStyleDone
target:myParent
action:@selector(captureViewImage)];
self.navigationItem.rightBarButtonItem = rightButton;
[rightButton release];
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc]
initWithTitle:@"Cancel"
style:UIBarButtonItemStyleBordered
target:myParent
action:@selector(dismissFileNamingFormSheet)];
self.navigationItem.leftBarButtonItem = leftButton;
[leftButton release];
self.title = @"Save As?";
}
return self;
}
// UITextFieldDelegate
- (void)textFieldDidEndEditing:(UITextField *)textField {
[fileNameField resignFirstResponder];
}
- (void)viewDidLoad {
[fileNameField becomeFirstResponder];
[super viewDidLoad];
}
fileNamer is initialized and released as follows:
- (void)presentFileNamingFormSheet {
fileNamer = [[Fil开发者_JAVA技巧eNamingViewController alloc]
initWithNibName:nil
bundle:nil
parent:self];
fileNamingNavCtrl = [[UINavigationController alloc]
initWithRootViewController:fileNamer];
fileNamingNavCtrl.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:fileNamingNavCtrl
animated:YES];
// resize modal form sheet
fileNamingNavCtrl.view.superview.frame = CGRectMake(0, 0, 540, 115);
// reposition modal form sheet
CGPoint position = CGPointMake(self.view.center.x, self.view.center.y - 50);
fileNamingNavCtrl.view.superview.center = position;
}
- (void)dismissFileNamingFormSheet {
[fileNamer release];
[fileNamingNavCtrl release];
[self dismissModalViewControllerAnimated:YES];
}
Output from Time Profiler:
Running (Self) Symbol Name
1109.0ms 37.0% argb32_image_mark_rgb32
328.0ms 10.9% blkclr
171.0ms 5.7% lo_alltraps
134.0ms 4.4% pmap_enter
116.0ms 3.8% png_write_find_filter
102.0ms 3.4% pmap_remove_range
55.0ms 1.8% pmap_get_mapwindow
47.0ms 1.5% vm_page_lookup
47.0ms 1.5% ml_set_interrupts_enabled
43.0ms 1.4% vm_page_grab
38.0ms 1.2% OSAddAtomic64
34.0ms 1.1% hw_lock_to
31.0ms 1.0% alphaProviderGetBytes
30.0ms 1.0% hw_lock_unlock
26.0ms 0.8% png_read_filter_row
25.0ms 0.8% deflateInit_
23.0ms 0.7% vm_map_lookup_entry
23.0ms 0.7% adler32
22.0ms 0.7% memory_object_recover_named
I found out what was causing this. The image I was saving contained a lot of transparent views. For example, I had a lot of UIButtons which had an alpha value of 0.05 to make them more or less disappear. I didn't realise I could just set the button type to custom to make it invisible (I created the view along time ago). Once I set everything in my image view to have an alpha value of 1.0, the saving process became a lot quicker.
精彩评论