我正在重构我的应用程序以确保它符合MVC。 我想拆分控制器(扩展UIController的MyController)和视图(扩展UIView的HomeView)我在myController中使用
设置视图self.view = [[HomeView alloc] init];
当我按下UIButton时,在视图中调用一个方法,在这个方法中我想从控制器调用一个方法。
在我看来
[zenModeBtn addTarget:self action:@selector(touchZenMode:) forControlEvents:UIControlEventTouchDown];
...
- (void) touchZenMode:(id) sender {
[myController playZenMode];
}
但在视图中引用控制器实际上是一种不好的做法不是吗?
编辑:
所以在我的UIViewController中我做到了:
- (id) init {
HomeView* myHomeView = [[HomeView alloc] init];
[myHomeView.arcadeModeBtn addTarget:self action:@selector(touchArcadeMode) forControlEvents:UIControlEventTouchUpInside];
self.view = myHomeView;
return self;
}
是正确的吗?
答案 0 :(得分:6)
与您的控制器交谈的视图没有问题,如此处的一些答案所述。例如。文本字段可以通过定义的委托方法通知其控制器。
但是,您的设计仍然存在严重缺陷。您的视图绝对没有处理按钮本身的业务。你认为视图不应该知道它的控制器的直觉是正确的。
您的控制器应该知道该按钮以及如何对其进行反应。这就是为什么控制器有按钮IBOutlet
来告诉按钮例如更改其标题或启用状态。它有按钮处理程序来响应UI事件。控制器的工作就是处理这个逻辑。视图的作用是显示标题,灰显或将敲击事件发送回控制器。
您应该在视图中添加的唯一代码基本上是如何绘制自己。 无法由控制器处理的所有内容。
答案 1 :(得分:3)
在Cocoa Touch中使用的MVC模式的基本思想:
如下所述:The Model-View-Controller Design Pattern
你想要实现的是一种松散的,甚至是盲目的偶然形式。通过使用协议(用于委托机制),View
只知道有一个对象采用特定的协议,它可以“交谈”。
以UITableView
为例。它不需要知道某种类型的UIViewController
可以帮助它收集数据,但只需要知道有一个对象采用UITableViewDatasourceDelegate
和/或UITableViewDelegate
;该对象可以是任何类型。
在编辑中,您使用目标操作机制,这是实现松散耦合的另一种方法。您在运行时设置连接;您的视图不知道您的控制器。因此:正确,除了@Mundi关于您的init
实施不完整的评论。
答案 2 :(得分:0)
视图需要某种方式将事物传达回控制器,询问下一步该做什么等问题。所以对于视图来说,了解控制器的信息是完全正确的。
某些内置视图(如UITextField)定义了用于告知其代理人正在发生的事情或要求其执行某些操作的协议。您通常在控制器中实现协议。这样,视图对控制器的了解并不多,只是足以进行通信。这使您的视图更通用和可重用。
您要避免的是,您的视图可以直接链接到模型。控制器的作用是在视图和模型之间进行调解。您应该能够在不触及模型的情况下完全更改视图的实现方式,反之亦然。
答案 3 :(得分:0)
您可以将该方法放在视图界面中的协议中:
@protocol MyViewDelegateProtocol <NSObject>
-(void)myMethod;
@end