2011-12-07 45 views
4

我有一個UITableViewController彈出一個UIImagePickerController,用戶需要一個圖片,點擊使用按鈕,Picker關閉顯示一個自定義的縮略圖旋轉器,而圖像正在處理,然後微調器被替換爲實際縮略圖在結束處理。爲什麼不會dismissmodalviewcontrolleranimated立即關閉ios5的UIImagePickerController?

至少這就是它在iOS4中的工作原理。現在iOS5只是在那裏處理,直到完成,然後一切正常。但我希望那裏的微調,讓用戶知道發生了什麼,否則它看起來就像掛了。

所以我有這樣的:

- (void) actionSheet: (UIActionSheet *)actionSheet didDismissWithButtonIndex (NSInteger)buttonIndex { 
    UIImagePickerController *picker = [[UIImagePickerController alloc] init]; 
    picker.delegate = self; 
    picker.allowsEditing = NO; 
    // yada, yada, yada 
    [self presentModalViewController:picker animated:YES]; 
    [picker release]; 
} 

然後這個被調用,當用戶拿起「使用」:

- (void) imagePickerController: (UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 
    [self dismissModalViewControllerAnimated:YES]; 
    [self performSelectorOnMainThread:@selector(processImage:) withObject:info waitUntilDone:NO]; 
    animate = true; 
} 

然後這個被調用,而縮略圖是旋轉來進行處理:

- (void) processImage:(NSDictionary *)info 
{ 
    UIImage *image = nil; 
    NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType]; 
    // processing of image 
    animate = false; 
    [activityImageView stopAnimating]; 
    [activityImageView release]; 
    [self.tableView reloadData]; 
} 

就像我說的那樣,它與iOS4完美協作,但與iOS5一樣,沒有這樣的運氣。那麼交易是什麼?圖像採集器最終被解僱,爲什麼它不會立即被解僱?

+0

我真的不知道爲什麼它應該沒關係,但是你試過更換'[自performSelector ...'和'dispatch_async (dispatch_get_main_queue(),^ {[self processImage:info];});'? – NJones

+0

好想法,但同樣的行爲。至少我學到了新東西! – mutatron

回答

4

我不確定爲什麼在這一點上有iOS4 & iOS5之間的差異。但是你對UI掛起的描述與你所展示的代碼相當一致。主線程上的執行選擇器就是這樣做的,在主線程上執行選擇器,這是您從中調用的線程。由於這個設置waitUntilDone:NO是沒有意義的,因爲它沒有被髮送到另一個線程,它只是按順序運行。你可能剛剛從交換順序,像這樣得到你想要的結果:

[self dismissModalViewControllerAnimated:YES]; 
animate = true; 
[self performSelectorOnMainThread:@selector(processImage:) withObject:info waitUntilDone:NO]; 

但請注意,這將是有風險的最好,因爲我認爲// processing of image不含併發。我更喜歡用於併發的塊。而最重要的是我喜歡的嵌套塊,使併發容易執行,例如:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ 
    [self dismissModalViewControllerAnimated:YES]; 
    [self processImage:info]; 
} 

-(void)processImage:(NSDictionary *)info{ 
    animate = true; 
    UIImage *image = nil; 
    NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType]; 

    dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
     // processing of image here on background thread 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      // update UI here on main thread 
      animate = false; 
      [activityImageView stopAnimating]; 
      [activityImageView release]; 
      [self.tableView reloadData]; 
     }); 
    }); 
} 

這會:

-(void)doSomeStuffInBackground{ 
    // Prepare for background stuff 
    dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
     // Do background stuff 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      // Update UI from results of background stuff 
     }); 
    }); 
} 

所以考慮到這一點,我會更喜歡這個建議的東西將主要工作卸載到後臺線程以使UI保持響應。

+0

完美!這正是我想要的,我也學到了一些東西。其實,我現在記得在我參加的課堂上學到了這樣的東西,但我想它並不符合我的要求。謝謝! – mutatron

0

嘗試使用

[[picker presentingViewController] dismissViewControllerAnimated:YES completion:nil]; 

代替:

[[picker parentViewController] dismissModalViewControllerAnimated: YES]; 
+0

歡迎來到Stack Overflow!感謝您的發佈!請勿在您的帖子中使用簽名/標語。您的用戶箱計爲您的簽名,您可以使用您的個人資料發佈您喜歡的任何關於您自己的信息。 [關於簽名/標語的常見問題](http://stackoverflow.com/faq#signatures) –