ios 如何在 Swift 中为 UIView 子类编写自定义初始化?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24339145/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I write a custom init for a UIView subclass in Swift?
提问by Doug Smith
Say I want to init
a UIView
subclass with a String
and an Int
.
假设我想要init
一个UIView
带有 aString
和 an的子类Int
。
How would I do this in Swift if I'm just subclassing UIView
? If I just make a custom init()
function but the parameters are a String and an Int, it tells me that "super.init() isn't called before returning from initializer".
如果我只是子类化,我将如何在 Swift 中做到这一点UIView
?如果我只是创建一个自定义init()
函数但参数是一个字符串和一个 Int,它会告诉我“在从初始化程序返回之前没有调用 super.init()”。
And if I call super.init()
I'm told I must use a designated initializer. What should I be using there? The frame version? The coder version? Both? Why?
如果我打电话,super.init()
我被告知我必须使用指定的初始化程序。我应该在那里使用什么?框架版?编码器版本?两个都?为什么?
回答by Wolf McNally
The init(frame:)
version is the default initializer. You must call it only after initializing your instance variables. If this view is being reconstituted from a Nib then your custom initializer will not be called, and instead the init?(coder:)
version will be called. Since Swift now requires an implementation of the required init?(coder:)
, I have updated the example below and changed the let
variable declarations to var
and optional. In this case, you would initialize them in awakeFromNib()
or at some later time.
该init(frame:)
版本是默认的初始值设定项。只有在初始化实例变量后才必须调用它。如果此视图是从 Nib 重构的,则不会调用您的自定义初始值设定项,而是init?(coder:)
会调用版本。由于 Swift 现在需要实现 required init?(coder:)
,我更新了下面的示例并将let
变量声明更改为var
和 可选。在这种情况下,您将在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)
}
}
回答by MH175
I create a common init for the designated and required. For convenience inits I delegate to init(frame:)
with frame of zero.
我为指定的和所需的创建了一个通用的 init。为了方便初始化,我委托给init(frame:)
零帧。
Having zero frame is not a problem because typically the view is inside a ViewController's view; your custom view will get a good, safe chance to layout its subviews when its superview calls layoutSubviews()
or updateConstraints()
. These two functions are called by the system recursively throughout the view hierarchy. You can use either updateContstraints()
or layoutSubviews()
. updateContstraints()
is called first, then layoutSubviews()
. In updateConstraints()
make sure to call super last. In layoutSubviews()
, call super first.
零帧不是问题,因为通常视图在 ViewController 的视图中;您的自定义视图将在其父视图调用layoutSubviews()
或updateConstraints()
. 这两个函数由系统在整个视图层次结构中递归调用。您可以使用updateContstraints()
或layoutSubviews()
。updateContstraints()
首先被调用,然后layoutSubviews()
。在updateConstraints()
确保调用 super last。在layoutSubviews()
,叫超级第一。
Here's what I do:
这是我所做的:
@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
}
}
回答by J-Dizzle
Here is how I do it on iOS 9 in Swift -
这是我在 Swift 中的 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"); }
}
Here is a full project with example:
这是一个带有示例的完整项目:
回答by J-Dizzle
Here is how I do a Subview on iOS in Swift -
这是我如何在 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"); }
}