Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在Init函数外部初始化类属性_Ios_Swift - Fatal编程技术网

Ios 在Init函数外部初始化类属性

Ios 在Init函数外部初始化类属性,ios,swift,Ios,Swift,如果这是一个基本问题,很抱歉,但我在任何地方都找不到解决方案。我想在Init之外的函数中初始化类属性,并且只从构造函数内部调用它。我这样做是为了避免代码重复,因为当前版本如下所示: public class WifiNameDisplay: UIView { var wifiImageView: UIImageView var networkName: UILabel public var networkSSID: String { didSet {

如果这是一个基本问题,很抱歉,但我在任何地方都找不到解决方案。我想在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)))
    }
}
我想把它改成这样:

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都获得了投票权。