【问题标题】:Why shouldn't I subclass a UIButton?为什么我不应该继承 UIButton?
【发布时间】:2012-10-23 12:30:29
【问题描述】:

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

子类化UIButton 有什么负面影响?我知道这很模糊,但是还有什么可以替代 UIButton 的子类?

【问题讨论】:

  • 您将 UIButton 子类化的原因是什么?指定按钮类型custom。还需要什么?
  • 我在问更多只是如果我想在未来子类化,为什么我不应该这样做。但现在我的应用程序中将有大约 20 个按钮,它们具有相同的背景、字体、文本周围的填充大小等。所以我想通过子类化来保持相同的时间和代码。
  • 没有理由不能继承 UIButton。事实上,我这样做是为了使用 IB 来定义按钮的外观。为什么?设计灵活性。很多人都继承了 UIButton。我已经继承了 UIButton。这种认为不可能的信念被重复但缺乏证据。
  • 子类化UIButton 与其他组件一样完全没问题。但对于更复杂的子类化(如自定义标签、imageViews 等)UIControl 子类总是更好的主意。

标签: objective-c ios uibutton uikit subclass


【解决方案1】:

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

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

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

编辑,你自己的工厂方法

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

@interface UIButton ( MyCompanyFactory )
+(UIButton *) buttonWithMyCompanyStyles;
@end
@implementation UIButton
+(UIButton *) buttonWithMyCompanyStyles {
    UIButton *theButton = [UIButton buttonWithType:UIButtonTypeCustom];
    // [theButton set...
    return theButton;
}
@end

【讨论】:

  • 虽然对设计很重要,但我不确定“偏好组合”是否真的是这个问题的好答案,因为UIButton 在这方面实际上是特殊的。我当然不会投反对票,因为你的帖子确实提出了很好的观点(事实上,我投了赞成票)。
  • @justin,我总是支持良好的对话!您是否在任何地方写博客,或者在某处有相关讨论的链接?
  • 我在关于这个主题的回答中添加了一个来自 Cocoa-Dev 列表的链接。如果您想联系我,当然欢迎您通过 twitter 私下或公开给我发消息(句柄在我的 SO 个人资料中)。我不写博客 - SO 是我的主要编码水冷却器。我保持低调。
  • 如何将此类别应用于使用情节提要添加到 UIViewController 的 UIButton?我尝试在 UIViewControllers.m 文件中导入类别,但没有成功。我错过了什么吗?
  • @2rec 不幸的是,您不能告诉 Storyboard 使用自定义工厂方法在其中创建按钮。我的建议是,如果您想在 Storyboard 创建的按钮中使用可重复使用的预定按钮样式集,只需在 Storyboard 中使用复制/粘贴,或创建(而不是工厂方法)UI 配置方法作为类别在 UIButton 上,然后在 viewDidLoad 或 viewDidAppear 中的按钮上调用该方法
【解决方案2】:

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


On implementing a subclass of UIButton

【讨论】:

  • @Nate,修复它。
【解决方案3】:

如果你只是想用你自己的“子视图”寻找更轻量级的东西,你应该继承 UIControl。 UIButton 是 UIControl 的子类,可以处理事件,比如:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 2015-10-18
    • 2017-10-05
    • 2010-09-29
    • 2018-07-26
    • 1970-01-01
    相关资源
    最近更新 更多