【问题标题】:Cocoa Touch Objective-C: How to invoke the same ViewController twice?Cocoa Touch Objective-C:如何调用同一个 ViewController 两次?
【发布时间】:2011-06-16 18:50:15
【问题描述】:

我正在构建一个在 TabBarController 上加载 5 个项目的 iPhone 应用程序。

当应用加载时,第一个视图是一个音频播放器(MyAudioPlayerViewController 的一个实例)

假设用户开始在 MyAudioPlayerViewController 上播放歌曲,然后决定点击 第二个 Tab Bar Item,它在 UITableView 可供选择。用户做出一个选择,这会导致另一个 UITableView(有一些其他选项可供选择),然后他们做出另一个选择,导致最终的 ViewController,它也是一个音频播放器。

我需要这个最终的 UIViewController 与第一个播放初始歌曲的 SAME 相同,并且 不是 MyAudioPlayerViewController 的新实例.

为什么我需要这个配置?我需要它,因为在用户对上一个 UITableView 做出最终选择的那一刻,正在播放的歌曲必须停止

具有 MyAudioPlayerViewController 的最终视图必须能够访问正在播放音频的自定义 NSObject 类,使其停止当前歌曲。

现在我有这段代码正在调用显示最终 UIViewController 的 MyAudioPlayerViewController:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    MyAudioPlayerViewController * myAudioPlayerViewController = [[MyAudioPlayerViewController alloc] initWithNibName:@"MyAudioPlayerViewController" bundle:nil];
    [self.navigationController pushViewController:myAudioPlayerViewController animated:YES];   
    [myAudioPlayerViewController changeText:[arraySingerList objectAtIndex:indexPath.row] withSong:[arraySongList objectAtIndex:indexPath.row]];    
    [myAudioPlayerViewController release];    
} 

正如你所看到的,它创建了一个 MyAudioPlayerViewController 的新实例,这与应用程序启动时的第一个实例无关,然后我可以在我的自定义 NSObject 类(播放器本身)上调用该方法,负责停止上一个正在播放的音频,因为它受到保护。

对于这种情况是否有任何解决方案,或者我是否应该使用其他方法重新构建所有内容?

谢谢!

【问题讨论】:

    标签: iphone objective-c cocoa-touch uitableview uiviewcontroller


    【解决方案1】:

    因为它们是标签栏控制器的一部分,并说您的 MyAudioPlayerViewController 实例位于第一个标签中。你可以这样做,

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
        MyAudioPlayerViewController * myAudioPlayerViewController = nil;
        for ( UIViewController * viewController in self.tabBarController.viewControllers ) {
            if ( [viewController isMemberOfClass:[MyAudioPlayerViewController class]] ) {
                myAudioPlayerViewController = (MyAudioPlayerViewController *)viewController;
            }
        }
    
        if ( !myAudioPlayerViewController ) {
            NSLog(@"Couldn't retrieve player");
        }
    
        [myAudioPlayerViewController changeText:[arraySingerList objectAtIndex:indexPath.row] withSong:[arraySongList objectAtIndex:indexPath.row]];
        self.tabBarController.selectedIndex = 0;
        [self.navigationController popToRootViewControllerAnimated:YES]; 
    }
    

    这里我们访问标签栏中视图控制器列表中的第一个视图控制器并调用changeText:withSong:,因为它是我们的MyAudioPlayerViewController 实例。然后我们将当前选项卡移动到我们的音乐播放器,然后在下次用户可以重新开始时弹出到该导航控制器中的根视图控制器。根据需要修改此行为。

    【讨论】:

    • 我正在尝试这个,并会让你知道事情的进展。谢谢迪帕克!
    • 由于我使用 UINavigation 控制器来推送 UITableViews,我得到 [UINavigationController changeText: withSong:]: unrecognized selector sent to instance 0x480620。我应该改变什么?
    • 音频播放器在哪个标签?是不是也推到了UINavigationController
    • 音频播放器位于第一个选项卡中。它在加载初始屏幕后立即显示。它不是从任何 UINavigationController 推送的。我认为当我进入第二个选项卡并在 UITableviews 上进行两个选择时,第一个选项卡为零。另一件事,我像这样隐藏 TabBar: self.hidesBottomBarWhenPushed = YES;在调用 MyAudioPlayerViewController 之前
    • 我已经修改了答案中的代码并检查它是否记录任何内容或工作:)
    【解决方案2】:

    您需要能够从其他类中引用 MyAudioPlayerViewController 实例。如果您愿意,您可以通过您的应用委托来执行此操作。

    如果您的标签栏控制器是使用 Interface Builder 设置的,请在 MyAudioPlayerViewController 类的应用委托中创建一个 IBOutlet,并将其连接到 Interface Builder 中的 MyAudioPlayerViewController。

    如果您在代码中设置标签栏控制器,只需分配/初始化实例变量并将其设置为您的第一个标签。

    您需要设置其属性或创建访问器方法,以便您可以从其他类访问它。

    要设置属性,请打开您的应用委托 .h 文件并添加以下内容:

    @property (nonatomic, retain) IBOutlet MyAudioPlayerViewController *myAudioPlayerViewController;
    

    并在您的应用委托 .m 文件中添加以下内容:

    @synthesize myAudioPlayerViewController;
    

    然后:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
        YourAppDelegate *yourAppDelegate = (YourAppDelegate *)[UIApplication sharedApplication] delegate];
        MyAudioPlayerViewController * myAudioPlayerViewController = [yourAppDelegate myAudioPlayerViewController];
        [self.navigationController pushViewController:myAudioPlayerViewController animated:YES];   
        [myAudioPlayerViewController release];    
    } 
    

    有关 Objective-C 中属性的更多信息:http://cocoacast.com/?q=node/103

    【讨论】:

    • 非常感谢托马斯帮助我,托马斯!!!我正在使用 Interface Builder 并在我的 AppDelegate 上创建了 IBOutlet 并将其连接到 IB 上。如何创建访问器方法?我收到警告:找不到方法 myAudioPlayerViewController...
    • @Winston 我在上面添加了有关创建属性的信息。它会为你创建访问器方法。
    • 谢谢托马斯,你帮了我很多!我已经尝试过了,我再次收到警告说找不到该方法。我不知道为什么。谢谢!
    • @Winston 在 didSelectRowAtIndexPath 方法中添加了几行代码。将 YourAppDelegate 替换为适当的类!
    • 它可以工作,现在我正在做一些微调,隐藏并在底部显示 UITabBar。我会告诉你。再次感谢!
    【解决方案3】:

    为什么我需要这个配置?一世 需要它,因为在这一刻 用户使他的最终 上一个 UITableView 上的选择 正在播放的歌曲必须停止。

    一个简单的方法是让任何播放音频的对象在开始播放之前发布通知,并观察来自任何其他对象的相同通知。如果音频播放器收到此类通知,它应该停止当前正在播放的所有声音。

    这样,您可以拥有任意数量的音频播放器控制器,而不会互相干扰,但它们都不必知道其他任何一个。

    【讨论】:

    • 我有一个通知中心设置。我会考虑的。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多