let view = UIView()
是可以接受的,但唯一记录的UIView初始化程序是init(frame:CGRect)
具体来说,我正在尝试编写一个继承自UIView的新类,但此代码会抛出错误
class SquadHorizontalScrollViewCell: UIView {
init(var: FIRDataSnapshot){
super.init()
....
表示必须调用指定的初始化程序
答案 0 :(得分:4)
UIView
继承自 UIResponder
,后者继承自 NSObject
。
NSObject.init()
initializer 可在 UIView
上访问,但不能在替换此指定初始化程序的 NSObject
的子类上访问。
让我们考虑一个例子。
class A: NSObject {
init(_ string: String) { }
}
这会导致 let a = A()
的编译器错误 - 缺少初始值设定项的参数 #1,因为该初始值设定项替换了子类中 init()
的指定 NSObject
初始值设定项。
你只需要将子类的初始化器定义为一个convenience
初始化器:
class A: NSObject {
convenience init(_ string: String) {
self.init() // Convenience initializers must call a designated initializer.
}
}
let a = A()
现在可以编译了。
UIView
还可以与子类中定义的其他指定初始化程序一起编译,因为它的指定初始化程序在编译时是未知的。根据{{3}},如果以编程方式实例化,则init(frame:)
为指定初始化器,否则init()
为指定初始化器。这意味着 UIView
继承了 NSObject
指定的初始化程序,而不是像上面的例子那样替换它。
在您的示例中:
class SquadHorizontalScrollViewCell: UIView {
init(var: FIRDataSnapshot){
super.init()
我们看到指定的初始化器是init(frame: CGRect)
,所以你必须调用这个指定的初始化器。
答案 1 :(得分:0)
在某个时刻,您的视图需要使用某些内容初始化,这就是编译抱怨的原因,因为它无法找到如何开始自定义视图的初始化。因为最后,视图将从xib(init(coder aDecoder: NSCoder)
)或框架(init(frame: CGFrame)
)初始化。所以在这里,最简单的方法是至少在自定义init方法中调用super.init(frame: CGRectZero)
。
init (var: FIRDataSnapshot) {
super.init(frame: CGRectZero)
}
// This method below is always needed when you want to override your init method
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
但你仍然需要设置框架的大小等。
答案 2 :(得分:0)
对于UIView
init(frame: CGRect)
是默认初始值设定项。初始化实例变量后必须调用它。如果您从NIB
查看视图,则会调用init?(coder aDecoder: NSCoder)
而不是init(frame: CGRect)
。因此,在这种情况下,您必须在awakeFromNib()
方法中初始化您的实例变量。在这种情况下,您的代码应该是这样的:
class SquadHorizontalScrollViewCell: UIView {
init(firDataSnapshot: FIRDataSnapshot){
// intialize your instance variable
super.init(frame: CGRectZero) // set your expected frame. For demo I have set `CGRectZero`
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
有关详细信息,请查看此链接https://developer.apple.com/reference/uikit/uiview
答案 3 :(得分:0)
指定的初始化程序应该将其超类称为初始化程序。
在这种情况下,super.init()
是NSObject
而不是UIView
的指定初始值设定项。
UIView有责任调用UIResponder init,我猜它没有指定初始值设定项,因此UIView会在其Super.init
初始值设定项中调用init(frame:CGrect)
。检查“初始化程序委派”
为什么let x = UIView()
没问题,因为这个
与Objective-C中的子类不同,Swift子类不会继承 默认情况下,它们的超类初始值设定项。斯威夫特的方法阻止了 继承超类中的简单初始值设定项的情况 由一个更专业的子类,用于创建一个新的实例 未完全或正确初始化的子类。 (苹果)
因为UIView是客观的c类,它仍然可以做到。但你不能调用SquadHorizontalScrollViewCell(),除非你没有提供任何初始化程序或你覆盖超类的指定初始化程序(UIView)
检查此link以获取更多信息
答案 4 :(得分:0)
您会注意到,如果您创建自己的 UIView
子类并且仅使用日志语句覆盖 init(frame:)
,然后仅使用 init()
、您的 init(frame:)
实例化这个新类实际上是用零大小的帧调用的。所以指定的初始化程序仍然被调用。