使用Interface Builder对类别进行子类化

时间:2013-08-01 14:58:17

标签: ios interface-builder

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

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

对我来说,简化IB流程的唯一方法就是按照每个人推荐的方式进行,这似乎有些矛盾。

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

感谢。

3 个答案:

答案 0 :(得分:3)

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

将此文件放在application:didFinishLaunchingWithOptions:方法

中的AppDelegate文件中
if([UIButton conformsToProtocol:@protocol(UIAppearanceContainer)]){
    [[UIButton appearance] setBackgroundImage:[UIImage imageNamed:@"YourImage"] forState:UIControlStateNormal];
    //modify any other UIButton properties you want to set globally
}

答案 1 :(得分:2)

我没有看到你不应该将UIButton子类化的任何原因,特别是为了使你更容易配置IB。您提供的链接都没有解释为什么您不应该进行子类化,因此它们的断言似乎不可靠。另一方面,UIButton.h中UIButtonTypeCustom的存在给人的印象是框架作者计划用于UIButton子类。

答案 2 :(得分: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:填充它存储的东西(这就是为什么你得到一个错误,如“类不符合键值)对于“当你搞砸一个笔尖”的东西,所以如果在加载笔尖时对某些东西进行了分类,那么是的,nibs尊重类别,因为它只是使用initWithCoder ..然后填补空白。

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

nibs的另一种技术是使用

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

然后相应地迭代和自定义按钮(通过子类,类别,本地方法......)。如果您只想要一些自定义按钮,但这种方法非常有用,那么这种方法非常有用。