Ios 在Init函数外部初始化类属性
如果这是一个基本问题,很抱歉,但我在任何地方都找不到解决方案。我想在Init之外的函数中初始化类属性,并且只从构造函数内部调用它。我这样做是为了避免代码重复,因为当前版本如下所示:Ios 在Init函数外部初始化类属性,ios,swift,Ios,Swift,如果这是一个基本问题,很抱歉,但我在任何地方都找不到解决方案。我想在Init之外的函数中初始化类属性,并且只从构造函数内部调用它。我这样做是为了避免代码重复,因为当前版本如下所示: public class WifiNameDisplay: UIView { var wifiImageView: UIImageView var networkName: UILabel public var networkSSID: String { didSet {
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)))
}
}
我想把它改成这样:
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’”。我想要的是可能的,还是我被迫使用重复的代码?如果您将属性声明为隐式展开选项,那么您可以在调用超类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)))
}
}
据我所知,有两种方法。定义值时初始化这些值:
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元素
另一种方法是使变量(隐式展开)成为可选的,并在super.init
之后调用initDefaultValues
:
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)))
}
}
将要在init函数外部初始化的属性更改为lazy属性:
lazy var networkName:UILabel = { return UILabel(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 400,
height: self. wifiImageView.frame.size.height)))}()
非常感谢,我会接受这个答案,因为你比我快了一分钟:)不过你和@libec都获得了投票权。