很抱歉,如果这是一个基本问题,但我无法在任何地方找到解决方案。我想在Init之外的函数中初始化类属性,并且只从构造函数内部调用它。我这样做是为了避免代码重复,因为当前版本看起来像这样:
public class WifiNameDisplay: UIView {
var wifiImageView: UIImageView
var networkName: UILabel
public var networkSSID: String {
didSet {
networkName.text = networkSSID
adjustSizeToContent()
}
}
override public init(frame: CGRect) {
networkSSID = "NETWORK"
wifiImageView = UIImageView(image: UIImage(named: "wifi_icon.png")!)
networkName = UILabel(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 400, height: wifiImageView.frame.size.height)))
super.init(frame: frame)
}
convenience public init() {
self.init(frame: CGRect.zero)
}
required public init(coder aDecoder: NSCoder) {
networkSSID = "NETWORK"
wifiImageView = UIImageView(image: UIImage(named: "wifi_icon.png")!)
networkName = UILabel(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 400, height: wifiImageView.frame.size.height)))
super.init(coder: aDecoder)!
}
}
我想把它改成这样的东西:
public class WifiNameDisplay: UIView {
var wifiImageView: UIImageView
var networkName: UILabel
public var networkSSID: String {
didSet {
networkName.text = networkSSID
adjustSizeToContent()
}
}
override public init(frame: CGRect) {
initDefaultValues()
super.init(frame: frame)
}
convenience public init() {
self.init(frame: CGRect.zero)
}
required public init(coder aDecoder: NSCoder) {
initDefaultValues()
super.init(coder: aDecoder)!
}
func initDefaultValues() {
networkSSID = "NETWORK"
wifiImageView = UIImageView(image: UIImage(named: "wifi_icon.png")!)
networkName = UILabel(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 400, height: wifiImageView.frame.size.height)))
}
}
问题是编译器不允许这样做,在super.init初始化self之前调用“在方法调用'initDefaultValues'中使用'self'”。我想要的甚至可能,还是我被迫使用重复代码?
答案 0 :(得分:1)
如果您将属性声明为隐式解包的选项,那么您可以在调用超类init函数后初始化它们 -
public class WifiNameDisplay: UIView {
var wifiImageView: UIImageView!
var networkName: UILabel!
public var networkSSID: String! {
didSet {
networkName.text = networkSSID
// adjustSizeToContent()
}
}
override public init(frame: CGRect) {
super.init(frame: frame)
initDefaultValues()
}
convenience public init() {
self.init(frame: CGRect.zero)
}
required public init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
initDefaultValues()
}
func initDefaultValues() {
networkSSID = "NETWORK"
wifiImageView = UIImageView(image: UIImage(named: "wifi_icon.png")!)
networkName = UILabel(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 400, height: wifiImageView.frame.size.height)))
}
}
答案 1 :(得分:1)
据我所知,有两种方法。在定义值时初始化值:
public class WifiNameDisplay: UIView {
var wifiImageView = UIImageView(image: UIImage(named: "wifi_icon.png")!)
var networkName = UILabel(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 400, height: wifiImageView.frame.size.height)))
public var networkSSID = "Network"
}
但这对您不起作用,因为networkName
在此范围内不了解wifiImageView
,因此无法为其找到正确的框架。我发现这对于设置偏移量,字符串常量等简单用例很有用,但是不建议将其用于UI元素。
其他方法是使变量(隐式解包)可选,并在initDefaultValues
之后调用super.init
:
public class WifiNameDisplay: UIView {
var wifiImageView: UIImageView!
var networkName: UILabel!
public var networkSSID: String! {
didSet {
networkName.text = networkSSID
}
}
override public init(frame: CGRect) {
super.init(frame: frame)
initDefaultValues()
}
required public init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
initDefaultValues()
}
func initDefaultValues() {
networkSSID = "NETWORK"
wifiImageView = UIImageView(image: UIImage(named: "wifi_icon.png")!)
networkName = UILabel(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 400, height: wifiImageView.frame.size.height)))
}
}
答案 2 :(得分:0)
将要在init函数之外初始化的属性更改为lazy属性:
lazy var networkName:UILabel = { return UILabel(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 400,
height: self. wifiImageView.frame.size.height)))}()