Доступ к методу экземпляра в другом контроллере представления - PullRequest
0 голосов
/ 06 января 2011

У меня есть контроллер панели вкладок с 4 вкладками. Каждая вкладка имеет свой собственный контроллер представления и UIWebView.

Допустим, у меня есть кнопка (button1) в vc1 и метод экземпляра onClick1. В vc2 у меня есть метод с именем reload. У меня вопрос, как мне получить доступ к конкретному методу экземпляра, onClick1 в vc2, из vc1?

Для более подробной информации, я на самом деле пытаюсь написать простую утилиту для покупок для iPhone. Когда пользователь добавляет товар в корзину из вида просмотра, я хочу иметь возможность автоматически перезагружать вид корзины.

Ниже приведены некоторые примеры того, что я имею в виду. Эта проблема оказалась сложнее, чем я думал. Я не уверен, изменил ли я свое приложение или как. Возможно, vc1 и vc2 принадлежат подклассу vcmain и имеют ссылку на каждый из них? Однако, если я это сделаю, то как мне отнести их к соответствующему .xib? Спасибо, ребята!

@implementation viewController 1

//Reloads vc2
-(IBAction) onClick1: (id) sender {

 //Calls vc2 reload
 [vc2 reload];
 }

@end

@implementation viewController 2

//Reload View
-(void)reload {
  [webView reload];
}

@end

Ответы [ 2 ]

1 голос
/ 06 января 2011

У вас есть три подхода, каждый из которых имеет свои плюсы и минусы.Я собираюсь дать вам общий обзор и позволить вам перейти к довольно полной документации Apple для деталей.Надеюсь, я могу дать вам правильные термины в Google для получения более конкретной помощи.

Подход, который @dredful довольно умело описывает, - это , чтобы иметь дескриптор "другого" контроллера (ов) представления и вызывать методына них напрямую .Это прекрасно работает, но это может сбивать с толку и обременительно передавать указатели всем вашим контроллерам, и обход иерархии представления для получения нужного контроллера действительно может быть очень сложным.

Второй подход - Наблюдение значения ключа .Вы можете зарегистрировать один контроллер представления, чтобы «наблюдать» за определенным ключом (именованным свойством) другого контроллера представления и запускать определенный селектор, когда с ним происходят разные вещи.Это довольно волшебно и приятно, хотя в какой-то момент вам нужно иметь указатели на оба контроллера в одно и то же время, что не полностью освобождает от недостатков метода «вызвать его напрямую», описанного выше.Это также своего рода неудачное соединение управления просмотром и данными, своего рода разрывы MVC.

Третий подход - с использованием NSNotificationCenter .Класс может опубликовать уведомление, и любой другой объект, который регистрируется для прослушивания такого рода уведомлений, может быть запущен, когда это произойдет.Это хорошо, потому что у вас может быть МНОЖЕСТВО различных объектов, добавляющих элементы в корзину, и они могут просто выстрелить в центр уведомлений заметку (даже передавая ей объект или произвольные данные, если он этого хочет), и представление корзины может использовать эти уведомления,лови пропущенные предметы и делай свое дело, не обращая особого внимания на то, кто с ним разговаривает.Он хорошо разделяет отдельные части вашего приложения.Недостатком является то, что в этом есть некоторые накладные расходы, и любой селектор, выполняемый классом, использующим уведомления, происходит синхронно, поэтому вы не можете скрыть сетевую активность или какой-либо другой длинный процесс там.

0 голосов
/ 06 января 2011

Я думаю, у вас уже должно быть что-то вроде базы UIViewController (назовем ее MyTabBars), в которой есть UITabBarController *tabBarController, содержащая все ваши контроллеры панели вкладок.Если это звучит знакомо, вам понадобится метод в MyTabBars с именем -(void)reloadCart.reloadCart будет проходить массив tabBarController.viewControllers.На каждом viewController вы можете выполнить respondsToSelector:@selector(reload), и, если конкретный viewController квалифицируется, он вызывает этот метод селектора.

Для того, чтобы сделать это, вы, вероятно, захотите все свои vc1, vc2, ...файлы для определения и синтеза id delegate.Когда MyTabBars создает различные панели вкладок, он устанавливает vc1 и vc2 delegate на self.

@implementation MyTabBars

//Reload Cart View
-(void)reloadCart {
  for (UIViewController *thisUIViewController in tabBarController.viewControllers){
     if ([thisUIViewController respondsToSelector:@selector(reload)]) {
         [thisUIViewController reload];
     }
  }
}

@end

Предполагая, что вы знаете, как передать делегата MyTabBars в ваши vc1 и vc2,тогда вы можете теперь иметь следующий код в vc1:

@implementation viewController1

//Reloads vc2
-(IBAction) onClick1: (id) sender {

 //Calls MyTabBars reloadCart which will look for all tab bar view controllers
 //that have the 'reload' method
 [delegate reloadCart];
 }

@end

Эта идея решения заставит MyTabBars вызвать любой метод reload, найденный в любом из наших контроллеров представления панели вкладок.Поэтому будьте осторожны с именами такого метода в файлах vc1, vc2 и т. Д.Это решение будет запускать уникальный метод vc или несколько vcs с одним и тем же методом в зависимости от вашего соглашения об именах.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...