Answers:
该init(frame:)
版本是默认的初始化程序。您必须在初始化实例变量之后才调用它。如果从Nib重构此视图,那么将不会调用您的自定义初始化程序,而是init?(coder:)
会调用版本。由于Swift现在需要实现required的实现,因此init?(coder:)
我更新了以下示例,并将let
变量声明更改为var
and可选。在这种情况下,您可以在awakeFromNib()
或稍后进行初始化。
class TestView : UIView {
var s: String?
var i: Int?
init(s: String, i: Int) {
self.s = s
self.i = i
super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
init(coder:)
。
s
并且i
Optional是为了使事情保持简单。如果它们不是可选的,则还需要在所需的初始化程序中对其进行初始化。将它们设置为可选意味着它们将nil
在super.init()
被调用时出现。如果它们不是可选的,则确实需要在调用super.init()之前对其进行分配。
我为指定的和必需的创建一个通用的init。为了方便起见,我将init(frame:)
零帧委托给它。
零帧不是问题,因为通常该视图在ViewController的视图内;您的自定义视图将在父视图调用layoutSubviews()
或时获得一个安全的机会来布局其子视图updateConstraints()
。系统在整个视图层次结构中递归调用这两个函数。您可以使用updateContstraints()
或layoutSubviews()
。updateContstraints()
首先被调用,然后被调用layoutSubviews()
。在updateConstraints()
请确保调用超级最后。在layoutSubviews()
,叫超级第一。
这是我的工作:
@IBDesignable
class MyView: UIView {
convenience init(args: Whatever) {
self.init(frame: CGRect.zero)
//assign custom vars
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
commonInit()
}
private func commonInit() {
//custom initialization
}
override func updateConstraints() {
//set subview constraints here
super.updateConstraints()
}
override func layoutSubviews() {
super.layoutSubviews()
//manually set subview frames here
}
}
commonInit
方法中初始化某些属性,但是super
在这种情况下不能放置在该属性之后,该怎么办,因为您应该在super
调用之前初始化所有属性。大声笑似乎死循环。
这是我在Swift 9中的iOS 9上执行的操作-
import UIKit
class CustomView : UIView {
init() {
super.init(frame: UIScreen.mainScreen().bounds);
//for debug validation
self.backgroundColor = UIColor.blueColor();
print("My Custom Init");
return;
}
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented"); }
}
这是带有示例的完整项目:
super.init
,但他说应该在super.init
... 之前完成
这是我在Swift中的iOS上做子视图的方法-
class CustomSubview : UIView {
init() {
super.init(frame: UIScreen.mainScreen().bounds);
let windowHeight : CGFloat = 150;
let windowWidth : CGFloat = 360;
self.backgroundColor = UIColor.whiteColor();
self.frame = CGRectMake(0, 0, windowWidth, windowHeight);
self.center = CGPoint(x: UIScreen.mainScreen().bounds.width/2, y: 375);
//for debug validation
self.backgroundColor = UIColor.grayColor();
print("My Custom Init");
return;
}
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented"); }
}
var
。但是Swift中的默认最佳实践是声明变量,let
除非有理由声明它们var
。因此,在我上面的代码示例中没有这样的理由let
。