如何在一个视图控制器中执行操作在另一个视图控制器中启动另一个操作?

时间:2016-01-07 18:59:18

标签: ios objective-c

iOS开发新手& Objective-C并且有点不确定如何解决这个问题。

我正在开发一个像视频播放器一样工作的项目。有两个ViewControllers:

  • MenuViewController(有一个充当按钮的标题列表)
  • PlayerViewController(查看视频播放的位置)

在MenuViewController中,我希望能够点击按钮(视频标题):

- (IBAction)videoOne:(id)sender
{
    PlayerViewController * vc = [[PlayerViewController alloc] initWithNibName:@"PlayerViewController" bundle:nil];

    [self presentModalViewController:vc animated:YES];
}

并在PlayerViewController中定义的操作在加载后立即自动执行。

有没有办法让一个ViewController中的按钮在第二个ViewController加载后立即调用另一个ViewController中的动作?

谢谢!

3 个答案:

答案 0 :(得分:2)

解决此问题的正确方法是在两个视图控制器之间设置委托模式。

示例:

@protocol PlayerViewControllerDelegate<NSObject>
{
    -(void)playerViewControllerViewDidLoad:(PlayerViewController *)playerVC;
}

然后,在PlayerViewController.h中创建一个弱委托变量:

@property (nonatomic, weak) id<PlayerViewControllerDelegate> delegate;

在PlayerViewController.m中,通知viewDidLoad上的代理人:

-(void)viewDidLoad {

    [super viewDidLoad];

    [self.delegate playerViewControllerViewDidLoad:self]

}

在MenuViewController中:

- (IBAction)videoOne:(id)sender
{
    PlayerViewController * vc = [[PlayerViewController alloc] initWithNibName:@"PlayerViewController" bundle:nil];
    vc.delegate = self
    [self presentViewController:vc animated:YES];
}

最后,在MenuViewController中实现协议,你准备好了:

@interface MenuViewController : UIViewController<PlayerViewControllerDelegate>

@end

@implementation MenuViewController

-(void)playerViewControllerViewDidLoad:(PlayerViewController*)playerVC
{
    [playerVC playVideo];
}

@end

答案 1 :(得分:2)

让一个控制器控制另一个控制器的行为通常不是好习惯。相反,您可以让MenuViewController创建PlayerViewController并设置变量,以便新玩家知道如何根据其内部状态进行操作。

为了在控制器的生命周期中执行操作,您可以覆盖多种UIViewController方法。根据您的问题,您似乎想要viewDidLoad方法。

我不确定您是如何在控制器之间传递视频的,但如果您使用的是URL(例如Youtube视频),那么您可以执行以下操作:

// MenuViewController.m
- (IBAction)videoOne:(id)sender {

    PlayerViewController* vc = [[PlayerViewController alloc] initWithNibName:@"PlayerViewController" bundle:nil];

    // Pass any necessary data to the controller before displaying it
    vc.videoURL = [self getURLForSender:sender];

    [self presentViewController:vc animated:YES completion:nil];
}

// PlayerViewController.m
- (void)viewDidAppear {
    // View did appear will only be called after the controller has displayed
    // its primary view as well as any views defined in your storyboard or 
    // xib. You can safely assume that your views are visible at this point.

    [super viewDidAppear];

    if (self.videoURL) {
        [self playVideo];
    }
}

您需要在PlayerViewController上定义属性videoURL并公开公开它。如果您使用的是本地文件(例如来自用户的照片存储),您可以在呈现之前将视频传递给新的视图控制器。

您可以覆盖其他UIViewController生命周期方法。我们会更深入地解释它们in this post以及Apple's UIViewController Documentation

修改:将presentModalViewController:animated:更改为presentViewController:animated:completion:并将viewDidLoad更改为viewDidAppear,因为它似乎更适合此问题。

答案 2 :(得分:1)

presentModalViewController:animated:已弃用。请改用presentViewController:animated:completion:

在完成块中,您可以在呈现的视图控制器上调用方法:

[self presentViewController:otherVC
                   animated:YES
                 completion:^{ [otherVC startPlaying]; }];

完成在提交的控制器viewDidAppear之后运行。