3

我多次阅读我们不应该子类化组件(例如 UIButton):

问题是当我使用 Interface Builder 时。例如,我在很多视图中都有一个外观精确的按钮。我可以每次都用 IB 设置它们(这很痛苦),或者我可以使用自定义类来分解自定义行为和外观。

对我来说,简化 IB 流程的唯一方法就是按照每个人都反对的方式来做这件事,这对我来说似乎有点矛盾。

有更好的解决方案吗?我可以在 IB 中使用类别吗?

谢谢。

4

3 回答 3

3

您也许可以使用 UIView 外观代理。我不知道你对按钮做了什么,但这可能会有所帮助:

把这是你的 AppDelegate 文件放在application:didFinishLaunchingWithOptions:方法中

if([UIButton conformsToProtocol:@protocol(UIAppearanceContainer)]){
    [[UIButton appearance] setBackgroundImage:[UIImage imageNamed:@"YourImage"] forState:UIControlStateNormal];
    //modify any other UIButton properties you want to set globally
}
于 2013-08-01T15:47:01.747 回答
2

您提供的第二个链接非常清楚,这几乎是苹果自己声明的子类,但绝不会弄乱内部结构。

最好的例子是 iOS 7,现在情况完全不同了,例如,我正在维护的一个应用程序有一个子类UIControl,现在它在新的 iOS 上运行时遇到了麻烦,仅仅是因为它是在假设内部结构如何构建的情况下构建的工作(迭代内部subviews替换一些东西)。您可能不会让您的应用程序被拒绝,但维护 a** 会很痛苦。

根据经验,您可以从外部对 UIButton 执行任何操作,如下所示:

[myButton setBackgroundImage:... forState:...];
[myButton setTextColor:... forState:...];
myButton.titleLabel.font = ...

您可以将其移动到自定义子类方法的内部:

+ (UIButton*)fancyPantsButton
{
    UIButton *button = [UIButton butonWithType:UIButtonTypeCustom];

    [myButton setBackgroundImage:... forState:...];
    [myButton setTextColor:... forState:...];
    myButton.titleLabel.font = ...

    return button;
}

您也可以在有问题initawakeFromNib没有问题的情况下执行此操作(我通常更喜欢后者)。

UIAppearence也是一个选项,正如用户 hw731 所建议的那样。不管你的船漂浮着什么,真的。

至于第二个问题,nib 文件几乎创建了一个类的实例,然后setValue:forKey:在加载时填写它存储的东西(这就是为什么当你搞砸一个笔尖),所以如果在加载笔尖时对某些内容进行了分类,那么是的,笔尖尊重类别,因为它只是使用initWithCoder.. 然后填补空白。

而且,出于同样的原因,nib 文件将无法填写自定义属性,因为它不知道它们,除非您在 IB(iOS 5 及更高版本)的“用户定义的运行时属性”中明确添加它们)。

笔尖的另一种技术是使用

@property (strong) IBOutletCollection(UIButton) NSArray *buttons;

然后相应地迭代和自定义按钮(通过子类、类别、本地方法……)。如果您只需要少量自定义按钮,但不足以保证使用子类,则此方法非常有用。

于 2013-08-01T22:39:08.933 回答
2

我看不出有任何理由不应该继承 UIButton,尤其是为了让 IB 的配置更容易。您提供的两个链接都没有解释为什么您不应该子类化,因此他们的断言似乎并不可靠。另一方面,UIButtonTypeCustom在 UIButton.h 中的存在给人的印象是框架作者计划为 UIButton 子类。

于 2013-08-01T20:58:37.670 回答