iOS:如何让 ViewController A 模态呈现 B,然后让 B 直接关闭/转换到模态呈现的 C?

Posted

技术标签:

【中文标题】iOS:如何让 ViewController A 模态呈现 B,然后让 B 直接关闭/转换到模态呈现的 C?【英文标题】:iOS: How can I have ViewController A present B modally and then have B dismiss/transition directly to a modally presented C? 【发布时间】:2013-06-18 05:36:20 【问题描述】:

现在我有一个 ViewController(“A”),它以模态方式呈现用户的 iPod 库(“B”):

// This works great
- (void)selectSong  // UIBarButtonSystemItemAdd target action
    MPMediaPickerController *picker = [[MPMediaPickerController alloc] init];
    picker.delegate = self;
    [self presentViewController:picker animated:YES completion:NULL];

我通过委托从“A”中解散模态呈现的 VC,“B”:

- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection 
    // Do stuff with selected item...

    // Set up modal transition style and then dismiss
    [mediaPicker setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
    [mediaPicker dismissViewControllerAnimated:YES completion:^
        // Launch capture screen
        // DOING IT THIS WAY CLEARLY SHOWS VIEW "A" BEFORE WE SEE VIEW "C"
        // I'M LOOKING FOR A WAY I CAN DISMISS THE MODAL IPOD MUSIC PICKER
        // VIA "FLIP" DIRECTLY TO VIEW CONTROLLER "C" (WHICH DOES SOMETHING
        // WITH THE SELECTED SONG).
        [self performSegueWithIdentifier:@"captureViewController" sender:self];
    ];

有了这个实现,技术上一切正常。我不喜欢的是 ViewController A 呈现 B 和 C 的方式,用户可以在它解除 B 之后和呈现 C 之前看到 ViewController A。我希望 A 呈现 B 然后 B 直接解除/过渡到C. 我怎样才能做到这一点?

*更新:另请注意,如果我将手动 segue 调用放在完成块之外,那么我会收到关于同时呈现两件事的错误。如果我将动画切换为 NO,我会得到一个不同的错误。

【问题讨论】:

【参考方案1】:

在情节提要中给captureViewController 一个标识符。

- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection 
    // Do stuff with selected item...

    // Set up modal transition style and then dismiss

    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"STORYBOARDNAME" bundle:nil];
    UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:@"captureViewController"];
    [self presentModalViewController:vc animated:NO];

    [mediaPicker setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
    [mediaPicker dismissViewControllerAnimated:YES completion:nil];

【讨论】:

这看起来很有希望。我试了一下,收到以下错误消息:Warning: Attempt to present <CaptureViewController: 0x1c5affb0> on <UINavigationController: 0x1d83af60> whose view is not in the window hierarchy!【参考方案2】:

试试这个,

- (void)selectSong  // UIBarButtonSystemItemAdd target action
    MPMediaPickerController *picker = [[MPMediaPickerController alloc] init];
    picker.delegate = self;
 [self performSegueWithIdentifier:@"captureViewController" sender:self];
    ];
    [self presentViewController:picker animated:YES completion:NULL];

【讨论】:

这种方法将 captureViewController 放在 iPod 歌曲选择器之前的屏幕上。用户永远没有机会选择歌曲。

以上是关于iOS:如何让 ViewController A 模态呈现 B,然后让 B 直接关闭/转换到模态呈现的 C?的主要内容,如果未能解决你的问题,请参考以下文章

iOS点击推送通知打开具体的viewcontroller

iOS 给 ViewController 减负 之 UITableView

iOS 将storybord中的视图与viewcontroller相关联

IOS 教你玩转UITableViewController和TableView

故事板中的PresentModalViewController以编程方式iOS 5

Vue 如何接受IOS传过来的window数据