封装 iOS 逻辑
Encapsulating iOS logic
我正在创建一个 UITextField
来格式化数字。我最初的想法是我将 subclass UITextField
并将格式化数字的逻辑添加到此 subclass。我的想法是,这个逻辑和我的mainViewController没有关系,应该封装到控件本身。
所以现在我有一个子class。我现在需要做的就是监听一个事件,例如 - (BOOL)textField: shouldChangeCharactersInRange: replacementString:
.
然而,将委托设置为 self 似乎不是一个好的设计实践,我不得不说我有点惊讶。将控制逻辑封装在 subclass 而不是视图控制器或完全独立的 class.
中对我来说是完全有意义的
我目前的方法是向 UITextField
添加一个目标操作,它会侦听任何更改 - 但这感觉不对。我想使用委托,但它似乎不受欢迎。
因此,如果委托方法只是为了传递给其他对象,对象应该如何封装与这些事件相关的逻辑,而不使用通知或 KVO 或类似的东西?
为什么应该将事件的处理交给 ViewController 而实际上应该由控件来处理该逻辑?
在 iOS/OS X 中,给 UI 元素很多自己的逻辑是不常见的,因为这违反了 Cocoa 的 Model-View-Presenter 设计(Apple 称之为 Model -View-Controller,但 Cocoa MVC 不像 classic MVC,而是像 MVP)。在 MVP 中,视图尽可能地转储。他们唯一的任务就是展示他们被告知要展示的东西。这就是为什么他们被称为"Presenters",他们只会呈现一些东西。
而在 Cocoa 中,通过 subclass 扩展功能并不常见。 Cocoa 是围绕组合和委托设计的。所以你用简单的组件构建复杂的组件(这称为组合)并有一个委托来定制功能,所以通常不需要子class你的class。
UI 元素的逻辑通常在控制器对象中。 Model是数据,controller是逻辑,presenter/view就是UI.
如果您想将所有这些封装在一个 class 中,请不要使用 subclassing,请使用组合。 Subclass UIView
创建自定义视图并在该视图中使用普通 UITextField
:以编程方式创建它,将其保存在实例变量(或私有 属性)中,将它作为子视图添加到自己([self addSubview:...]
),然后将自己设置为它的委托来处理事件。
当然subclassing UIView
也是subclassing,但是subclassing UIView
是创建自定义的唯一方法视图(否则 UIView
必须是一个协议)并且它非常简单,因为您几乎不需要覆盖任何东西,并且您需要(或可能想要)覆盖的内容已得到很好的记录。
考虑 UIView
实际上是为 subclassing 设计的(文档中有很多关于 subclassing 的注释),UITextField
不是(这个词subclassing 甚至不存在于其文档中)。 Objective-C 没有 final
关键字来防止 subclassing,所以按照惯例,考虑所有 classes final 除非有 subclassing 注释(如果有是这样的关键字,UITextField
最喜欢是 final
).
我正在创建一个 UITextField
来格式化数字。我最初的想法是我将 subclass UITextField
并将格式化数字的逻辑添加到此 subclass。我的想法是,这个逻辑和我的mainViewController没有关系,应该封装到控件本身。
所以现在我有一个子class。我现在需要做的就是监听一个事件,例如 - (BOOL)textField: shouldChangeCharactersInRange: replacementString:
.
然而,将委托设置为 self 似乎不是一个好的设计实践,我不得不说我有点惊讶。将控制逻辑封装在 subclass 而不是视图控制器或完全独立的 class.
中对我来说是完全有意义的我目前的方法是向 UITextField
添加一个目标操作,它会侦听任何更改 - 但这感觉不对。我想使用委托,但它似乎不受欢迎。
因此,如果委托方法只是为了传递给其他对象,对象应该如何封装与这些事件相关的逻辑,而不使用通知或 KVO 或类似的东西?
为什么应该将事件的处理交给 ViewController 而实际上应该由控件来处理该逻辑?
在 iOS/OS X 中,给 UI 元素很多自己的逻辑是不常见的,因为这违反了 Cocoa 的 Model-View-Presenter 设计(Apple 称之为 Model -View-Controller,但 Cocoa MVC 不像 classic MVC,而是像 MVP)。在 MVP 中,视图尽可能地转储。他们唯一的任务就是展示他们被告知要展示的东西。这就是为什么他们被称为"Presenters",他们只会呈现一些东西。
而在 Cocoa 中,通过 subclass 扩展功能并不常见。 Cocoa 是围绕组合和委托设计的。所以你用简单的组件构建复杂的组件(这称为组合)并有一个委托来定制功能,所以通常不需要子class你的class。
UI 元素的逻辑通常在控制器对象中。 Model是数据,controller是逻辑,presenter/view就是UI.
如果您想将所有这些封装在一个 class 中,请不要使用 subclassing,请使用组合。 Subclass UIView
创建自定义视图并在该视图中使用普通 UITextField
:以编程方式创建它,将其保存在实例变量(或私有 属性)中,将它作为子视图添加到自己([self addSubview:...]
),然后将自己设置为它的委托来处理事件。
当然subclassing UIView
也是subclassing,但是subclassing UIView
是创建自定义的唯一方法视图(否则 UIView
必须是一个协议)并且它非常简单,因为您几乎不需要覆盖任何东西,并且您需要(或可能想要)覆盖的内容已得到很好的记录。
考虑 UIView
实际上是为 subclassing 设计的(文档中有很多关于 subclassing 的注释),UITextField
不是(这个词subclassing 甚至不存在于其文档中)。 Objective-C 没有 final
关键字来防止 subclassing,所以按照惯例,考虑所有 classes final 除非有 subclassing 注释(如果有是这样的关键字,UITextField
最喜欢是 final
).