您提供的第二个链接非常清楚,这几乎就是苹果自己所说的子类,但绝不会弄乱内部结构。
最好的例子是 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;
}
您也可以在init 或awakeFromNib 上毫无问题地执行此操作(我通常更喜欢后者)。
UIAppearence 也是一个选项,正如用户 hw731 所建议的那样。不管你的船是什么,真的。
至于第二个问题,nib 文件几乎创建了一个类的实例,然后在加载时使用setValue:forKey: 填充它存储的内容(这就是为什么你会收到类似“类不符合键值对某些东西”的错误“当你搞砸笔尖时),所以如果在加载笔尖时对某些内容进行分类,那么是的,笔尖尊重类别,因为它只是使用initWithCoder..然后填补空白。
而且,出于同样的原因,nib 文件将无法填写自定义属性,因为它不知道它们,除非您在 IB 中的“用户定义的运行时属性”中明确添加它们( iOS 5 以上)。
笔尖的另一种技术是使用
@property (strong) IBOutletCollection(UIButton) NSArray *buttons;
然后相应地迭代和自定义按钮(通过子类、类别、本地方法……)。如果您只需要几个自定义按钮,但不足以保证使用子类,则此方法非常有用。