子类化UITextView(和UICollectionView)的问题是指定的构造函数是“initWithFrame”。但在现实生活中,当它从故事板加载时,将调用initWithCoder。
class BorderedTextView: UITextView {
//will be called
init(coder: NSCoder?){
//constant values here is not an option
super.init(frame: CGRectMake(0,0,100,100), textContainer: nil)
}
//will not be called
init(frame: CGRect, textContainer: NSTextContainer!) {
super.init(frame: frame, textContainer: textContainer)
}
}
结果我无法在init上调用任何UI自定义代码,并为除默认值之外的Swift变量提供任何初始化值。
我认为通过从“编码器”中提取帧大小可以暂时解决问题,但我没有找到它的关键。
任何想法都比硬编码帧值好吗?
答案 0 :(得分:12)
(来自我上面的评论:) 这看起来像是一个Swift错误。当initWithCoder:
被调用时
视图(或视图控制器)从Storyboard或Nib文件实例化,并覆盖
该方法适用于Objective-C:
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
// Initialization code
}
return self;
}
但等效的Swift代码
class BorderedTextView: UITextView {
init(coder: NSCoder!) {
super.init(coder: coder)
}
}
失败并显示错误消息"必须调用超类的指定初始值设定项' UITextView'"。
UIView
的所有子类都有此问题
他们自己的指定初始值设定项(例如UITextView
,UICollectionView
)。
另一方面,UILabel
的子类不会出现问题
没有指定的初始化程序。
Swift语言对于调用超级课程非常严格。指定初始化程序,
但应该有一种方法可以覆盖所有自定义initWithCoder:
子类的UIView
,所以我认为这是一个Swift错误。
作为解决方法,您可以在
中进行自定义初始化override func awakeFromNib() {
super.awakeFromNib()
// ...
}
更新Swift 1.2:这显然已得到修复。参数 改变了,它不再是一个隐式解包的可选项。所以这 编译并按预期工作(使用Xcode 6.4测试):
class BorderedTextView: UITextView {
required init(coder: NSCoder) {
super.init(coder: coder)
// ...
}
}
Swift 2(Xcode 7)的更新: init(coder:)
是可用的
初始化程序现在:
class BorderedTextView: UITextView {
required init?(coder: NSCoder) {
super.init(coder: coder)
// ...
}
}
答案 1 :(得分:-1)
Swift 3的更完整答案:
class ValidatedTextField:UITextField, UITextFieldDelegate
{
required override init(frame: CGRect)
{
super.init(frame: frame)
//custom code
self.delegate = self
}
required init?(coder: NSCoder)
{
super.init(coder: coder)
//custom code
self.delegate = self
}