2016-01-07 4 views
0

Новое в разработке iOS & Цель-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?

Спасибо!

+0

Использование делегатов для достижения того, что вам нужно. Или передайте значение/флаг другому контроллеру представления, и когда u загрузите этот контроллер просмотра, проверьте это значение и загрузите необходимые методы. –

+0

Вы можете попробовать передать блок. Похоже, что PlayerViewController знает «когда» (завершенная загрузка), а MenuViewController знает «как» (что должно быть сделано). Таким образом, вы передадите блок («как») из MenuViewController в PlayerViewController, который затем выполнит этот блок в соответствующее время («когда»). – CrimsonChris

ответ

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

presentModalViewController:animated: устарела. Вместо этого используйте presentViewController:animated:completion:.

В завершение блока, вы можете вызвать метод на представленном контроллере представления:

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

Завершение выполняется после того, как представил диспетчерское viewDidAppear.

+0

Я не знал, что могу назвать это в блоке завершения. является ли это альтернативой делегатам в этом случае? –

+0

Это не так гибко, @ Mr.T: вы не можете получить какую-либо информацию с тех пор, как Блок запускается сразу после появления представления, но вы можете сделать что-то простое. –

2

Обычно не рекомендуется использовать один контроллер, контролирующий поведение другого. Вместо этого вы можете создать MenuViewControllerPlayerViewController и установить переменные, чтобы новый игрок знал, как вести себя на основе его внутреннего состояния.

Существует несколько методов 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]; 
    } 
} 

Вы должны были бы определить свойство videoURL на PlayerViewController и публиковать его публично. Если вы используете локальные файлы (например, из хранилища фотографий пользователя), вы можете передать видео на новый контроллер представления перед его представлением.

Существуют и другие методы жизненного цикла UIViewController, которые вы можете переопределить. Они объясняются более подробно in this post, а также Apple's UIViewController Documentation.

Изменить: изменил presentModalViewController:animated: на presentViewController:animated:completion: и изменил viewDidLoad на viewDidAppear, поскольку это более подходит к вопросу.

+0

@JoshCaswell спасибо за примечание, я отредактировал ответ –

Смежные вопросы