36

我已经问了几个关于子类化 a 的堆栈溢出问题UIButton,并且有几个人告诉我我不应该子类化 a UIButton

子类化 a 的负面影响是UIButton什么?而且我知道这很模糊,但是子类化 a 的其他替代方法是UIButton什么?

4

3 回答 3

36

Cocoa 框架采用对象组合模式比传统的类层次结构更合适的方法。

一般来说,这意味着 UIButton 上可能有一个属性,您可以在其中设置另一个对象来处理按钮的各个方面。这是“自定义”按钮工作方式的首选方式。

这种模式的主要原因之一是许多库组件创建按钮并且不知道您希望它们创建子类的实例。

编辑,你自己的工厂方法

我注意到您上面的评论是,当您在应用程序中的多个按钮上使用相同的按钮配置时可以节省时间。这是使用工厂方法设计模式的好时机,在 Objective-C 中,您可以使用 Category 来实现它,因此它可以直接在 UIButton 上使用。

@interface UIButton ( MyCompanyFactory )
+(UIButton *) buttonWithMyCompanyStyles;
@end
@implementation UIButton
+(UIButton *) buttonWithMyCompanyStyles {
    UIButton *theButton = [UIButton buttonWithType:UIButtonTypeCustom];
    // [theButton set...
    return theButton;
}
@end
于 2012-11-02T20:01:35.123 回答
16

这是因为UIButton它有点特殊,因为它需要一些复杂性/微妙性/限制(即您需要定义的额外覆盖,特别是+buttonWithType:),以便它按预期工作。它比平常更多-initWithFrame:(并且-initWithCoder:,如果在 XIB 中使用)。IDK 为什么框架作者允许这些细节泄露到我们的领域,但这是我们现在必须处理的事情。限制是您的实现不得依赖(即扩展)预设的系统按钮样式;您必须假设UIButtonTypeCustom作为子类的起点UIButton


关于实现一个子类UIButton

于 2012-11-02T20:20:15.660 回答
13

如果您只是在使用自己的“子视图”寻找更轻量级的东西,则应该将 UIControl 子类化。UIButton 是 UIControl 的子类,可以处理事件,例如:

[mySubclassedButtonFromUIControl addTarget:self action:@selector(_doSomething:) forControlEvents:UIControlEventTouchUpInside];

UIControl 是 UIView 的子类,因此您可以在 UIControl 子类包含的任何视图上干净地 layoutSubviews 并避免 UIButton 附带的不必要的视图。从本质上讲,您只是在创建自己的“UIButton”,但您不必处理您并不真正想要或不需要的行为和功能。

于 2015-06-10T19:13:17.380 回答