我正在创建一个格式化数字的UITextField
。我最初的想法是,我将子类UITextField
,并且格式化数字的逻辑将被添加到此子类中。我的想法是这个逻辑与我的主ViewController无关,它应该被封装到控件本身。
所以现在我有了一个子类。我现在需要做的就是听取- (BOOL)textField: shouldChangeCharactersInRange: replacementString:
等事件。
然而似乎将代表设置为自我并不是一个好的设计实践,我不得不说我有点惊讶。对于我来说,将控制逻辑封装在子类中而不是视图控制器或完全独立的类中是完全合理的。
我目前的做法是向UITextField
添加目标操作,以监听任何更改 - 但这感觉不对。我想使用委托,但似乎不赞成。
因此,如果委托方法仅用于传递给其他对象,那么对象应该如何封装与这些事件相关的逻辑,而不使用通知或KVO或类似的东西?
为什么要将事件的处理移交给ViewController,因为它真的是应该处理该逻辑的控件?
答案 0 :(得分:2)
在iOS / OS X中,为UI元素提供许多自己的逻辑是不常见的,因为这违反了Cocoa的Model-View-Presenter设计(Apple称之为模型 - 视图 - 控制器,但Cocoa MVC不像经典的MVC,但更喜欢MVP)。在MVP中,视图尽可能地转储。他们唯一的任务是展示他们被告知要展示的内容。这就是为什么他们被称为“演示者”,他们只会呈现一些东西。
在Cocoa中,通过子类扩展功能并不常见。 Cocoa是围绕构图和授权而设计的。因此,您可以使用简单组件(这称为组合)构建复杂组件,并具有自定义功能的委托,因此通常不需要为您的类创建子类。
UI元素的逻辑通常在控制器对象中。模型是数据,控制器是逻辑,演示者/视图只是UI。
如果要将所有这些封装在单个类中,请不要使用子类,请使用合成。子类UIView
创建自定义视图并在该视图中使用普通UITextField
:以编程方式创建它,将其保存在实例变量(或私有属性)中,将其作为子视图添加到自己({ {1}})然后将自己设置为处理事件的委托。
当然,子类化[self addSubview:...]
也是子类化,但子类化UIView
是创建自定义视图的唯一方法(否则UIView
必须是一个协议)并且它非常简单,
考虑UIView
实际上是为子类化而设计的(文档有很多关于子类化的注释),UIView
不是(子类化这个词甚至不存在于其文档中)。 Objective-C没有UITextField
关键字来阻止子类化,所以按照惯例,除非有子类注释,否则考虑所有类final(如果有这样的关键字,final
最像是UITextField
)。