如何在UIView / Subview响应链中组织类?

时间:2013-02-24 13:20:49

标签: objective-c design-patterns uiview

我经常听到,按照每个班级认识其他班级的方式组织班级并不好。 所以我试着让那些作为其他班级财产的班级不了解他们的父母。但是有了UIView,我无法实现它。

问题来自更通用的背景,因为问题不仅发生在UIViews上。 如果我有一辆汽车作为物体,4个车轮作为4个实例变量,当左前轮爆裂时。左后轮应该收到一条消息。我应该如何以良好的方式设计系统?

Objective-C中的UIView示例: 我有一个自定义的UIView填充整个屏幕。管理所有布局。假设只有2个子视图可以保持简单。

@interface BackgroundView : UIControllerView {

    CustomViewA *buttonA;
    CustomViewB *buttonB;
}
@end

@interface CustomViewA : UIButton

@interface CustomViewB : UIButton

现在如果有人按下按钮A,按钮B应该做某事(例如变红)。 我看到了几个选项:

  1. 将按钮A的代理设置为按钮B,因此A的所有事件都转到B的实现文件。如果不是所有事件都与按钮B有关,则会出现问题。
  2. 创建一个BackgroundView的单例,让按钮A获取按钮B的属性或调用BackgroundView中的方法,该方法将我的调用转发给按钮B.问题如果我想要多个背景,可以创建一个更高的类来拥有两个BackgroundViews(听起来不太好)。
  3. 为UIViews调用parent,然后调用2.调用方法或直接更改它。不使用UIView时出现问题,将功能复制到其他“父”类?
  4. 有没有更好的方法来解决这样的问题?或者我可以大大优化一种方法吗?

2 个答案:

答案 0 :(得分:2)

可能所有逻辑都属于ViewController,他知道他控制的视图的所有内容,但视图对视图控制器或彼此之间一无所知。

视图应该通过委托(或目标 - 动作)与视图控制器通信,并且视图控制器应该做出决策,并且可能将消息转发给其他视图。

顺便说一句,看看iTunes大学的斯坦福大学课程。我认为这是他们谈论MVC(模型视图控制器)的第一或第二类。这将有很大的帮助:https://itunes.apple.com/us/course/coding-together-developing/id593208016

答案 1 :(得分:2)

@Odrakir在这里提到模型 - 视图 - 控制器,他们是对的 - 这应该是你的第一站。如果它有帮助,这里是你如何将这种模式应用于你的例子:

您有一个带有属性color的模型类。在基于文档的应用程序中,文档通常 模型。在非基于文档的应用程序中,将模型挂起应用程序委托实例是很常见的。为简单起见,我们假设我们处于后一种情况。您可能有以下类:

// "Model"
@interface MyModel : NSObject
@property (nonatomic, readwrite, copy) UIColor* color;
@end

// AppDelegate
@interface MyAppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, readonly, retain) MyModel* model;
@end

// "View"
@interface CustomViewA : UIButton
@end

@interface CustomViewB : UIButton
@end

// "Controller"
@interface MyViewController : UIViewController

@property (nonatomic, readwrite, assign) IBOutlet UIView* buttonA;
@property (nonatomic, readwrite, assign) IBOutlet UIView* buttonB;

- (IBAction)doActionA: (id)sender;
- (IBAction)doActionB: (id)sender;

@end

基本模式是这样的:来自视图的动作触发控制器的模型修改动作(目标/动作模式)。要实现这一点,您可以通过将按钮A的操作连接到控制器上的-doActionA:(IB中的“文件所有者”)和(同样用于B)来连接它们。然后,控制器上的操作方法在被触发时应修改模型,并使由于模型更改而需要重绘的任何视图无效。您可以通过将视图插入控制器上的IBOutlet并让控制器调用[self.buttonA setNeedsDisplay]来完成此操作。然后,当您的视图绘制时,它应该从模型中读取需要正确绘制的任何状态。

值得一提的是,在MacOS上,您可以通过使用绑定将视图链接到模型来消除手动失效步骤。在这种情况下,对模型的更改将自动使视图无效。 iOS / UIKit没有绑定,因此您必须手动执行此操作失效。