Приложение для iPhone. Как один вид может вызвать метод в другом представлении?

Я делаю простое приложение для iPhone с панелью вкладок. У него есть две вкладки, одна с UIWebView, а другая с несколькими текстовыми полями для хранения настроек и кнопкой для сохранения настроек.

Что я хочу сделать, так это перезагрузить UIWebView, когда пользователь нажимает кнопку «Сохранить» на вкладке/представлении настроек. У меня уже есть сохранение настроек, мне просто нужно выяснить, как сделать вызов, чтобы UIWebView обновился.

Я не понимаю, как представление может отправлять сообщения другому представлению.


person Greg    schedule 05.05.2009    source источник


Ответы (5)


Тот факт, что вы используете эти два представления внутри структуры UITabBarController, не имеет отношения к сути проблемы; а именно, что вы хотите, чтобы одна часть вашего приложения сообщала, что что-то произошло в другой части. Типичный способ сделать это с помощью KVO или с помощью NSNotificationCenter следующим образом:

// Register interest in finding out when the settings are changed
[[NSNotificationCenter defaultCenter] addObserver:myWebViewController 
    selector:@selector(refreshWebView:) name:@"settingsSaved" object:nil];

// Notify interested parties that the settings have changed
[[NSNotificationCenter defaultCenter] postNotificationName:@"settingsSaved" object:nil];
person Nathan de Vries    schedule 06.05.2009
comment
Правильно, за исключением того, что я думаю, что KVO и уведомления звучат как излишество для этой проблемы. - person Rog; 06.05.2009

Я сделал так, чтобы они общались друг с другом через AppDelegate.

Например:

View1 будет иметь функцию, которая:

MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    [appDelegate myFunction];

В MyAppDelegate есть функция myFunction, которая либо что-то делает, либо вызывает:

[viewController myViewFunction];

Я настроил довольно удобную систему для загрузки нескольких представлений (и навигации вперед и назад, как если бы это были разные экраны). У меня просто не было времени написать это и опубликовать на pushplay.net, но я постараюсь сделать это в ближайшие пару дней...

===

РЕДАКТИРОВАТЬ: Хорошо, я разместил то, что у меня есть. Любые замечания будут оценены.

http://pushplay.net/blog_detail.php?id=27

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

person Jeffrey Berthiaume    schedule 05.05.2009
comment
Спасибо, это имеет смысл. Обязательно опубликуйте здесь, когда у вас будет подробное описание вашего поста. - person Greg; 06.05.2009
comment
Вам не нужно использовать делегат приложения для передачи сообщений в другие представления. Вот для чего нужны контроллеры представлений. - person Nathan de Vries; 06.05.2009
comment
Это правильный вид кода, но вы должны сделать это в viewController, как говорит Натан. Старайтесь не добавлять в appDelegate больше, чем необходимо. Он станет достаточно большим только с теми вещами, которыми он должен владеть. - person Rog; 06.05.2009

Это зависит от сложности конкретного приложения и объектной модели в этом приложении:

  • Если представления связаны, а сообщения относятся только к представлениям, тогда они могут отправлять друг другу сообщения напрямую. Например, представление может (и должно) отправлять сообщения непосредственно своим подчиненным представлениям, а они могут отправлять сообщения непосредственно своему родителю.

  • Если их представления не связаны, но отображают данные об одной и той же информации, вы должны проксировать сообщения через viewController - именно поэтому у вас есть контроллер представления.

  • Если у вас есть сложное приложение с сильной архитектурой MVC, взаимодействие должно осуществляться косвенно путем обновления объектов модели и каскадирования этого в представлениях через их контроллеры представлений.

person Rog    schedule 06.05.2009

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

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

person Kendall Helmstetter Gelner    schedule 06.05.2009

Вы всегда можете настроить переменную экземпляра в контроллере представления вкладок, которая указывает на веб-представление. Просто настройте его как IBOutlet, подключите его в Interface Builder, а затем вызовите свой метод для переменной экземпляра.

.h файл:

IBOutlet UIWebView *webView;

@property (nonatomic, retain) UIWebView *webView;

.м файл:

@synthesize webView;

//Then later in your method
[webView refresh]; //or however you do it

С уважением,

Кайл

person Kyle    schedule 07.05.2009