2010-07-09 52 views
7

我相信這是一個相當簡單的應用程序,目前基於一些教程拼湊在一起。我在OSX 10.6.4中使用XCode 3.2.3。它開始作爲一個標準的iPhone「基於窗口的應用程序」。使用Interface Builder我在這裏使用O'Reilly的視頻教程,增加了標籤欄控制器:iPhone應用程序中的例外情況:Modal轉換已在進行中

http://broadcast.oreilly.com/2009/06/tab-bars-and-navigation-bars-t.html

第一個選項卡我有一個標準的UIView有兩個按鈕。無論調用同一個函數來顯示的UIImagePickerController:

-(IBAction) btnPhotoClicked:(id)sender { 
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; 
imagePicker.delegate = self; 
if((UIButton *)sender == btnChoosePhoto) 
{ 
    imagePicker.allowsEditing = YES; 
    imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; 
} else { 
    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; 
} 

[self presentModalViewController:imagePicker animated:YES]; 
[imagePicker release]; 
} 

我運行一個仿真器內部的代碼,所以永遠只能點擊稱爲按鈕選擇照片。當對話框發佈時選擇了該功能:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 
NSURL *mediaUrl; 

mediaUrl = (NSURL *)[info valueForKey:UIImagePickerControllerMediaURL]; 

if (mediaUrl == nil) 
{ 
    imagePuzzle = (UIImage *) [info valueForKey:UIImagePickerControllerEditedImage]; 
    if(imagePuzzle == nil) 
    { 
     //--- Original Image was selected --- 
     imagePuzzle = (UIImage *) [info valueForKey:UIImagePickerControllerOriginalImage]; 
    } 
    else { 
     //--- Get the edited image --- 
     //--- If it was successful the above valueForKey:UIImagePickerControllerEditedImage 
     //--- would have assigned it already. 
    } 
} 
else { 
    //--- Muppet selected a video 
} 

// Animate the picker window going away 
[picker dismissModalViewControllerAnimated:YES]; 
ImageViewController *imageViewController = [[ImageViewController alloc] init]; 
imageViewController.delegate = self;  
[self presentModalViewController:imageViewController animated:YES]; 
[imageViewController release]; 
} 

這是我的問題所在。我已經嘗試了許多不同的黑客和迭代,但上面的代碼是最簡單的問題展示。當imageViewController顯示爲模式對話框時,會拋出以下異常:

2010-07-09 15:29:29.667 Golovomka[15183:207] *** Terminating app due to uncaught 
exception 'NSInternalInconsistencyException', reason: 'Attempting to begin a modal 
transition from <NewViewController: 0x5915f80> to <ImageViewController: 0x594a350>  
while a transition is already in progress. Wait for viewDidAppear/viewDidDisappear 
to know the current transition has completed' 

如何解決此問題?我嘗試過延遲和其他技巧,但並不真正瞭解我應該如何使用viewDidAppear或viewDidDisappear來幫助我。還值得注意的是,一個非常基本的應用程序加載選擇器,然後顯示另一個視圖與圖像不會產生錯誤。任何幫助感激地收到。

回答

9

爲了解決這裏所描述的具體問題,你可以在你的類中添加viewDidAppear方法:

-(void)viewDidAppear:(BOOL)animated 
{ 
    if (/*just visited ImagePicker*/) 
    { 
     ImageViewController *imageViewController = [[ImageViewController alloc] init]; 
     imageViewController.delegate = self;  
     [self presentModalViewController:imageViewController animated:YES]; 
     [imageViewController release]; 
    } 
} 

從您的通話下面的命令刪除這些行:

[picker dismissModalViewControllerAnimated:YES]; 

所以,當你的類self出現(顯示),它會調用viewDidAppear ...因爲這最有可能不是真的你一直想要什麼,你可以添加一些變量來設置/清除,定義是否要im當顯示self時,中介呈現imageViewController。像「如果來自圖像選擇器,顯示imageViewController,否則什麼都不做」。

也就是說,推動模態視圖的imho通常應該根據用戶的操作來完成,我可能會重新考慮這裏的用戶體驗 - 例如,添加一個子視圖,而不是推送一個模態視圖,你可以在當前擁有代碼的地方執行 - 但是如果你只是在玩一些應該解決NSInternalInconsistencyException的教程。 :)乾杯!

+0

謝謝你的建議,我會盡力,在我的代碼,它比我在做什麼整潔。在用戶拍攝照片或選擇照片後,我正在推動模式視圖。這裏的想法是,有一些潛在的激烈圖像處理,我想模式地顯示給用戶,直到它完成。所以在強制模態視圖之前需要用戶操作。撇開我最終殺死了這個異常:

[picker dismissModalViewControllerAnimated:YES]; [picker.view.superview removeFromSuperview];
Diziet 2010-07-10 11:51:04

+0

確定picker.view.superview removeFromSuperview。真的很糟糕的解決方案,除非你喜歡之後的所有內容都是空白的!我最終使用標籤欄應用程序中的導航欄控制器從頭開始重建應用程序,並且工作正常。另一方面,你的解決方案也有效。謝謝。現在更清楚了。我從C/C++/Java/Perl/bash背景中只做了兩天。 – Diziet 2010-07-10 18:50:41

0

當我想在解散UIImagePickerController後立即呈現MFMailComposeViewController時,我遇到了同樣的問題。繼承人我做了什麼:

  1. 我刪除從我在那裏,將圖像拾取的[imagePicker release];語句,並把它放在didFinishPickingMedia回調。

  2. 我用[self performSelector:@selector(presentMailComposer:) withObject:image afterDelay:1.0f];

這裏是我的代碼: 顯示圖片選擇器

if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { NSArray *media = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];

if ([media containsObject:(NSString*)kUTTypeImage] == YES) { 
     UIImagePickerController *picker = [[UIImagePickerController alloc] init]; 
     [picker setMediaTypes:[NSArray arrayWithObject:(NSString *)kUTTypeImage]]; 
     picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 
     picker.delegate = self; 
     [self presentModalViewController:picker animated:YES]; 
     //[picker release]; 
    } 

} 
else { 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Unavailable!" 
                message:@"Could not open the Photo Library." 
                delegate:nil 
              cancelButtonTitle:@"OK" 
              otherButtonTitles:nil]; 
    [alert show]; 
    [alert release]; 
} 

圖片選擇委託回調 - didFinishPickingMedia

NSString *mediaType = [info valueForKey:UIImagePickerControllerMediaType];

if([mediaType isEqualToString:(NSString*)kUTTypeImage]) { 
    UIImage *photoTaken = [info objectForKey:@"UIImagePickerControllerOriginalImage"]; 

    //Save Photo to library only if it wasnt already saved i.e. its just been taken 
    if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) { 
     UIImageWriteToSavedPhotosAlbum(photoTaken, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 
    } 

    //Pull up MFMailComposeView Controller 
    [self performSelector:@selector(composeMailWithPhoto:) withObject:photoTaken afterDelay:1.0f]; 
} 

[picker dismissModalViewControllerAnimated:YES]; 
[picker release]; 

顯示郵件撰寫查看

if ([MFMailComposeViewController canSendMail]) {

MFMailComposeViewController *mailPicker = [[MFMailComposeViewController alloc] init]; 
    mailPicker.mailComposeDelegate = self; 

    // Fill out the email fields and Attach photograph to mail 
    static NSString *imageType = @"image/jpeg"; 
    NSString *imageName = [NSString stringWithString:@"MyCoffeeCup.jpg"]; 
    NSData *imageData = UIImageJPEGRepresentation(image, 1.0); 

    [mailPicker addAttachmentData:imageData mimeType:imageType fileName:imageName]; 
    [mailPicker setToRecipients:[NSArray arrayWithObject:@"[email protected]"]]; 

    [self presentModalViewController:mailPicker animated:YES]; 
    //[self.navigationController pushViewController:mailPicker animated:YES]; 
    [mailPicker release]; 
} 
else { 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Unavailable!" 
                message:@"This device cannot send emails." 
                delegate:nil 
              cancelButtonTitle:@"OK" 
              otherButtonTitles:nil]; 
    [alert show]; 
    [alert release]; 
} 

2

我就遇到了這個問題好幾次。我最近開始使用這個簡單的修補程序:

當我打算在解散另一個模態視圖控制器後立即顯示一個新的模態視圖控制器時,我只需在dismissModalViewControllerAnimated:中忽略第一個帶有參數NO的第一個模態視圖控制器。

由於第二個視圖是用動畫呈現的,所以很難注意到第一個視圖快速消失。你永遠不會得到過渡衝突。

5

在安裝iOS 5.0及以上,你可以使用

[self dismissViewControllerAnimated:YES completion:^{ 
    //present another modal view controller here 
}]; 
+0

這很方便。 – Diziet 2012-11-05 09:52:03

+0

解決了我的導航問題。謝謝 – 2012-12-23 09:54:43

相關問題