1. ホーム
  2. xcode

互いに依存し合うプロパティを初期化する方法

2023-09-21 11:04:16

質問

画像を下に移動させたい。もし私がボタンを押したら、写真は1つ下に移動するはずです。

写真とボタンを追加しました。

var corX = 0
var corY = 0

var runter: UIButton = UIButton.buttonWithType(UIButtonType.System) as UIButton

var image = UIImage(named: "panzerBlau.jpg");
var panzer = UIImageView(frame: CGRectMake(corX, corY, 30, 40));  //

override func viewDidLoad() {
    super.viewDidLoad()

    panzer.image = image;    //
    self.view.addSubview(panzer);    //

    runter.frame = CGRectMake(100, 30, 10 , 10)
    runter.backgroundColor = UIColor.redColor()
    view.addSubview(runter)
    runter.addTarget(self, action: "fahren", forControlEvents:UIControlEvents.TouchUpInside)
}

少なくとも私は関数 "fahren" で、画像を1つ下に移動させると言いました。

func fahren(){
    corY += 1
    panzer.frame = CGRectMake(corX, corY, 30, 40) //
    self.view.addSubview(panzer);
}

私の問題は、これらのcorXとcorYの件でいくつかのエラーが発生することです。それらがなければ、それは完全に動作しますが、それは単一使用ボタンのようなものです。エラーは次のとおりです。ViewController.Type does not have a member named corX and ViewController.Type does not have a member names panzer どこでエラーが出るかというと、 // どの行に表示されるかを作りました。

PS:私はXcodeベータ5を使用しています。

以下は何もない完全なコードです。

import UIKit

class ViewController: UIViewController {

    var corX = 0
    var corY = 0
    var runter: UIButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
    var image = UIImage(named: "panzerBlau.jpg");
    var panzer = UIImageView(frame: CGRectMake(corX, corY, 30, 40));

    override func viewDidLoad() {
        super.viewDidLoad()
            panzer.image = image;
            self.view.addSubview(panzer);

        runter.frame = CGRectMake(100, 30, 10 , 10)
        runter.backgroundColor = UIColor.redColor()
        view.addSubview(runter)
        runter.addTarget(self, action: "fahren", forControlEvents:UIControlEvents.TouchUpInside)
    }

    func fahren(){
        corY += 100
        panzer.frame = CGRectMake(corX, corY, 30, 40)
        self.view.addSubview(panzer);
    }
}

どのように解決するのですか?

ここで、@MartinR が大きな問題を指摘しています。

var corX = 0
var corY = 0
var panzer = UIImageView(frame: CGRectMake(corX, corY, 30, 40))

問題は、Swift のデフォルトのイニシャライザは、初期化の時点でプロパティがまだ存在しないため (インスタンス自体がまだ存在しないため)、別のプロパティの値を参照できないことです。基本的には panzer のデフォルトイニシャライザーでは、暗黙のうちに self.corXself.corY - は存在しないが self なぜなら self は、まさに私たちが作っている最中のものだからです。

回避策としては、イニシャライザーを遅延させることです。

class ViewController: UIViewController {
    var corX : CGFloat = 0
    var corY : CGFloat = 0
    lazy var panzer : UIImageView = UIImageView(frame: CGRectMake(self.corX, self.corY, 30, 40))
    // ...
}

これは合法です。 panzer が初期化されるのは、実際のコードで最初に参照されるときだからです。その時までに self とそのプロパティは存在します。