2013-04-04 3 views
3

Я в настоящее время реорганизую свое приложение, чтобы убедиться, что он совместим с MVC. Я хотел бы разделить контроллер (MyController, который проходит UIController) и вид (HomeView, который проходит UIView) Я установить вид в myController с помощьюMVC - вид знает контроллер?

self.view = [[HomeView alloc] init]; 

Когда я вытолкнуть UIButton, метод вызывается в представлении , и в этом методе я хотел бы вызвать метод из контроллера.

На мой взгляд

[zenModeBtn addTarget:self action:@selector(touchZenMode:) forControlEvents:UIControlEventTouchDown]; 

...

- (void) touchZenMode:(id) sender { 
    [myController playZenMode]; 
} 

Но имея ссылку на контроллер в представлении действительно плохая практика, не так ли?

EDIT:

Так что в моем UIViewController я сделал это:

- (id) init { 
    HomeView* myHomeView = [[HomeView alloc] init]; 
    [myHomeView.arcadeModeBtn addTarget:self action:@selector(touchArcadeMode) forControlEvents:UIControlEventTouchUpInside]; 
    self.view = myHomeView; 
    return self; 
} 

правильно?

ответ

6

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

Тем не менее, ваш дизайн по-прежнему серьезно испорчен. У вашего взгляда абсолютно нет деловой обработки кнопки. Ваша интуиция, что представление не должно знать о его контроллере, верна.

Контроллер должен знать о кнопке и как реагировать на ее постукивание. Вот почему контроллер имеет кнопку IBOutlet s, чтобы указать кнопку, например. изменить его название или включенное состояние. И у него есть обработчики кнопок, чтобы реагировать на события пользовательского интерфейса. Задача контроллера - справиться с этой логикой. Это задача представления, чтобы отобразить заголовок, серый цвет или отправить событие крана обратно в контроллер.

Единственный код, который вы должны положить в представление, в основном, как рисовать сам. Все, что не может обработать контроллер.

+0

Спасибо, но кнопка тоже должна быть нарисована, поэтому я должен оставить ее в виде справа? – Max

+0

Можете ли вы посмотреть на меня? – Max

+0

Справа. Создайте и настройте кнопку в контроллере. Помните, что контроллер контролирует представление. - Но ваше редактирование неверно. в 'init' вам нужно вызвать' [[super alloc] init] 'для создания' self'. – Mundi

0

Представление должно каким-то образом передавать информацию контроллеру, задавать вопросы о том, что делать дальше и т. Д. Таким образом, это прекрасно для представления, чтобы что-то узнать о контроллере.

Некоторые из встроенных представлений, таких как UITextField, определяют протоколы, которые они используют, чтобы сообщить своему делегату о том, что происходит, или попросить его что-то сделать. Обычно вы выполняете протокол в своем контроллере. Таким образом, представление действительно мало знает о контроллере, достаточно для общения. Это делает ваш взгляд более универсальным и многоразовым.

Что вы хотите избежать, так это ваш взгляд на прямые ссылки на вашу модель. Роль контроллера заключается в посредничестве между представлением и моделью. Вы должны полностью изменить способ реализации представления, не касаясь модели, и наоборот.

0

Вы можете поместить этот метод в протоколе в интерфейсе вашего зрения в:

@protocol MyViewDelegateProtocol <NSObject> 
    -(void)myMethod; 
@end 
  • вы положили новое свойство типа NSObject называемый делегатом на ваш взгляд.
  • вы устанавливаете, что ваш контроллер просмотра соответствует этому протоколу, и когда он в представлении присваивает свойству делегирование самому себе.
  • Вы реализуете myMethod в своем представлении контроллера.
  • и теперь вы просто вызываете [delegate myMethod] с вашего вида, когда вам это нужно.
3

Основная идея шаблона MVC, используемый в Cocoa Touch:

Cocoa version of MVC as a compound design pattern

Как описано здесь: The Model-View-Controller Design Pattern

То, что вы хотите достичь, является одной из форм loose-, даже слепой, может быть, сцепление. Используя протоколы (для механизма делегирования), View знает только, что есть объект, который принимает определенный протокол, он может «говорить».

Возьмите, например, UITableView. Ему не нужно знать, что существует определенный тип UIViewController, который помогает ему собирать данные, но только тот объект, который принимает UITableViewDatasourceDelegate и/или UITableViewDelegate; этот объект может быть любого типа.

В вашем редактировании вы используете механизм целевого действия, который является другим способом достижения свободной связи. Вы настроили соединение во время выполнения; ваш View не знает ваш контроллер. Для этого: правильно, кроме комментария @Mundi сделал о вашей init реализации неполной.

+0

очень приятное объяснение спасибо – Max