写真を下に移動したいです。ボタンを押すと、写真が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)
}
少なくとも、機能「華氏」で、写真を1つ下に移動すると言いました。
func fahren(){
corY += 1
panzer.frame = CGRectMake(corX, corY, 30, 40) //
self.view.addSubview(panzer);
}
だから私の問題は:これらのcorXとcorYのことでいくつかのエラーが出ます。それらがなくても完全に機能しますが、使い捨てのボタンのようなものではありません。エラーは次のとおりです。ViewController.TypeにはcorXというメンバーがなく、ViewController.Typeにはメンバー名panzerがありません。
PS:Xcode Beta5を使用しています
以下に、他に何もない完全なコードを示します。
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.corX
およびself.corY
を参照しますが、self
は正確には何もないため、self
はありません。作成の途中。
1つの回避策は、初期化子を遅延させることです。
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
とそのプロパティが存在します。
依存プロパティは次のとおりである必要があります。
lazy
: Type
self.
他のプロパティにアクセスするには例:
let original = "foo"
// Good:
lazy var depend: String = self.original
// Error:
var noLazy: String = self.original // Error: Value of type '(NSObject) -> () -> URLData' has no member 'original'
lazy var noType = self.original // Error: Value of type '(NSObject) -> () -> URLData' has no member 'original'
lazy var noSelf: String = original // Error: Instance member 'original' cannot be used on type 'YourClass'
//
// ViewController.Swift
//
// Created by Shivank Agarwal on 19/05/18.
// Copyright © 2018 Shivank Agarwal. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
var corX = 0
var corY = 0
var runter: UIButton = UIButton()
var image = UIImage(named: "panzerBlau.jpg")
var panzer = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
panzer.image = image;
self.view.addSubview(panzer);
panzer.frame = CGRect(x: CGFloat(corX), y: CGFloat(corY), width: 30, height: 40)
runter.backgroundColor = UIColor.red
view.addSubview(runter)
view.addSubview(panzer)
runter.addTarget(self, action: Selector(("fahren")), for:UIControlEvents.touchUpInside)
}
private func fahren(){
corY += 100
}
private func updatePanzerFrame(){
panzer.frame = CGRect(x: CGFloat(corX), y: CGFloat(corY), width: 30, height: 40)
}
}
Note: Do not add panzer imageView every time when user tap only add it on viewDidLoad()
私は質問のタイトルに取り組んでいます:
遅延プロパティと計算プロパティは、オブジェクトの初期化後までプロパティの初期値がnotである場合に対処するのに役立ちます。しかし、いくつかの違いがあります。違いを太字で強調しました。
他の変数が初期化された後に変数を初期化する必要がある場合は、lazy
を使用する必要があります。つまり、単に遅延を追加する場合(したがって、必要なすべてのプロパティが初期化される)それのための正しい方法。
しかし、一定して変数を別の変数に基づいて変更する必要がある場合、両方とも機能する計算プロパティが必要です方法:
遅延プロパティの値を変更しても、それが基になっている名高いプロパティには影響しません。 こちら をご覧ください
遅延プロパティを使用する良い例は、firstName
とlastName
を取得したら、fullName
を遅延的にインスタンス化し、firstNameとlastNameを変更しないことです。オブジェクトのfullNameは1回限りです...または、おそらくlazy
プロパティでしかできないことは、プロパティにアクセスしない限り初期化されるまで、したがって、これはクラスの初期化ロードを減少します。 heavy計算の読み込み。
さらにlazy
を使用すると、他の開発者にとってsignalになります。「まず、他のプロパティについて読んで、その内容を理解してください...その後、この遅延プロパティに来てください...これの値はそれらに基づいているため+これはおそらくあまりにも早くアクセスされるべきではない重い計算です...」
計算されたプロパティに関しては、温度をFahrenheitに設定すると、摂氏の温度も変更したい場合の良い例です値...そして、摂氏温度を設定した場合、再び華氏値を変更します。
結果として、計算プロパティは追加の計算を追加します...そしてあなたの計算が非常に単純であまり頻繁に呼び出されない場合は心配することはありませんが、あまりにも頻繁に呼び出されるか非常にCPUを消費する場合はより良いかもしれません他のオプションを考える...