我多次阅读我们不应该子类化组件(例如 UIButton):
问题是当我使用 Interface Builder 时。例如,我在很多视图中都有一个外观精确的按钮。我可以每次都用 IB 设置它们(这很痛苦),或者我可以使用自定义类来分解自定义行为和外观。
对我来说,简化 IB 流程的唯一方法就是按照每个人都反对的方式来做这件事,这对我来说似乎有点矛盾。
有更好的解决方案吗?我可以在 IB 中使用类别吗?
谢谢。
我多次阅读我们不应该子类化组件(例如 UIButton):
问题是当我使用 Interface Builder 时。例如,我在很多视图中都有一个外观精确的按钮。我可以每次都用 IB 设置它们(这很痛苦),或者我可以使用自定义类来分解自定义行为和外观。
对我来说,简化 IB 流程的唯一方法就是按照每个人都反对的方式来做这件事,这对我来说似乎有点矛盾。
有更好的解决方案吗?我可以在 IB 中使用类别吗?
谢谢。
您也许可以使用 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
}
您提供的第二个链接非常清楚,这几乎是苹果自己声明的子类,但绝不会弄乱内部结构。
最好的例子是 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;
然后相应地迭代和自定义按钮(通过子类、类别、本地方法……)。如果您只需要少量自定义按钮,但不足以保证使用子类,则此方法非常有用。
我看不出有任何理由不应该继承 UIButton,尤其是为了让 IB 的配置更容易。您提供的两个链接都没有解释为什么您不应该子类化,因此他们的断言似乎并不可靠。另一方面,UIButtonTypeCustom
在 UIButton.h 中的存在给人的印象是框架作者计划为 UIButton 子类。