【发布时间】:2018-05-17 03:46:14
【问题描述】:
苹果的教程将init(frame:)和init?(coder:)的区别描述为
您通常通过以下两种方式之一创建视图:以编程方式 初始化视图,或者允许视图被 故事板。每种方法都有一个对应的初始化器:
init(frame:)用于以编程方式初始化视图和init?(coder:)用于从情节提要加载视图。你会需要 在您的自定义控件中实现这两种方法。尽管 设计应用程序时,Interface Builder 以编程方式实例化 将其添加到画布时查看。在运行时,您的应用会加载 从情节提要中查看。
我对“以编程方式初始化”和“由情节提要加载”的描述感到非常困惑。假设我有一个名为 MyView 的 UIView 的子类,“以编程方式初始化”是否意味着我编写代码以将 MyView 的实例添加到类似的地方:
override func viewDidLoad() {
super.viewDidLoad()
let myView = MyView() // init(frame:) get invoked here??
}
在 Main.storyboard 中调用 init?(coder:) 时,我从对象库中拖出一个 UIView,然后在身份检查器中将其类设置为 MyView?
此外,在我的 xcode 项目中,这两种方法最终会得到不同的模拟器布局,而 Main.storyboard 具有相同的代码:
import UIKit
@IBDesignable
class RecordView: UIView {
@IBInspectable
var borderColor: UIColor = UIColor.clear {
didSet {
self.layer.borderColor = borderColor.cgColor
}
}
@IBInspectable
var borderWidth: CGFloat = 20 {
didSet {
layer.borderWidth = borderWidth
}
}
@IBInspectable
var cornerRadius: CGFloat = 100 {
didSet {
layer.cornerRadius = cornerRadius
}
}
private var fillView = UIView()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupFillView()
}
override init(frame: CGRect) {
super.init(frame: frame)
setupFillView()
}
private func setupFillView() {
let radius = (self.cornerRadius - self.borderWidth) * 0.95
fillView.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: radius * 2, height: radius * 2))
fillView.center = CGPoint(x: self.bounds.midX, y: self.bounds.midY)
fillView.layer.cornerRadius = radius
fillView.backgroundColor = UIColor.red
self.addSubview(fillView)
}
override func layoutSubviews() {
super.layoutSubviews()
}
func didClick() {
UIView.animate(withDuration: 1.0, animations: {
self.fillView.transform = CGAffineTransform(scaleX: 0.6, y: 0.6)
}) { (true) in
print()
}
}
}
为什么他们的行为不同? (我从对象库中拖出一个UIView 并将其类设置为RecordView)
【问题讨论】:
标签: ios xcode uiview initwithcoder initwithframe