質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

1回答

542閲覧

タップした場所に表示させた画像をタップすることで消す方法を教えてください。

magiee

総合スコア28

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2020/04/07 03:01

前提・実現したいこと

1回目のタップで表示させた画像を、
2回目のタップで、表示させた画像を消したい場合は、
どのように記載させれば動くでしょうか?

ご教授のほど、よろしくお願い致します。

該当のソースコード

以下のコードでは、うまくいきませんでした。

import UIKit class ViewController: UIViewController { var coinCount = 0 @IBAction func addImage(_ sender: UITapGestureRecognizer) { if coinCount == 0 { let coin = UIImageView(image: UIImage(named: "myImage")) coin.center = sender.location(in: self.view) self.view.addSubview(coin) } else if coinCount == 1 { let coin = UIImageView(image: UIImage(named: "myImage")) coin.image = nil coin.setNeedsDisplay() coin.layoutIfNeeded() } coinCount = coinCount + 1 coinCount = coinCount % 3 } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } }

ご教授のほどよろしくお願いします。

発生している問題・メッセージ

エラーは特になし。

使用している言語

swift
Xvode 11.4

ご教授のほど、よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TsukubaDepot

2020/04/07 04:23

> coin.setNeedsDisplay() > coin.layoutIfNeeded() この2つの操作はなにか参考にして追加されたのでしょうか。 もし参考にされた情報があれば念のため教えてもらえますでしょうか。
guest

回答1

0

ベストアンサー

参考にされた過去の質問を見てみましたが、今回のご質問には必要ない操作だと思います。

今回の質問を解決するためには、まずは変数のスコープ(可視範囲)について理解する必要があると思います。

上記のリンクなどで、宣言した変数(やメソッドなど)がどの範囲まで有効になるかをまず確認してみてください。

さて、下記のコードですが、

swift

1if coinCount == 0 { 2 // 宣言【1】 3 let coin = UIImageView(image: UIImage(named: "myImage")) 4 coin.center = sender.location(in: self.view) 5 self.view.addSubview(coin) 6 // 宣言【1】の有効範囲はここまで 7} else if coinCount == 1 { 8 // 宣言【2】 9 let coin = UIImageView(image: UIImage(named: "myImage")) 10 coin.image = nil 11 coin.setNeedsDisplay() 12 coin.layoutIfNeeded() 13 // 宣言【2】の有効範囲はここまで 14}

宣言【1】coinという変数を定義していますが、有効なのは前述のリンク先の説明通り宣言【1】の有効範囲はここまでというところまでです。

一方、宣言【2】でもcoinという変数を定義していますが、これは宣言【1】で宣言したcoinという変数とは全く別の変数です。変数名は同じでも、スコープが違いますから別の変数として扱われます(逆に、同じスコープ内で同じ名前の変数を定義した場合、ごく一部の例外を除きコンパイルエラーとなります)

従って、宣言【2】

swift

1 coin.image = nil 2 coin.setNeedsDisplay() 3 coin.layoutIfNeeded()

と行っている操作は、宣言【2】で宣言しているcoinという変数に対する操作です。宣言【1】でサブビューに追加したcoinという変数とは実体が違うが名前が同じcoinという変数に操作しているため、宣言【1】で追加した画像を消すことはできません。

解決するためには、宣言【1】のブロック({}で囲まれた範囲)と宣言【2】のブロック両方で有効な変数を定義する必要があります。そのためには、もう一つ上の階層で変数を宣言する必要があります。

さらに、クリックしたときに画像を表示、あるいは消去するという操作を繰り返すためには、関数を再度呼び出しても有効に利用できる変数を用意する必要があります。

これらを考慮すると、このような感じに組み立てる必要があります。

swift

1class ViewController: UIViewController { 2 3 var coinCount = 0 4 // 複数回呼び出されても値を保持できるように、関数の外側で定義する 5 var coin: UIImageView = UIImageView() 6 7 @IBAction func addImage(_ sender: UITapGestureRecognizer) { 8 if coinCount == 0 { 9 // coinCount がゼロのとき 10 // 指定された画像をもとにImageViewを作る 11 coin = UIImageView(image: UIImage(named: "myImage")) 12 // ImageViewの中心座標をタップされた場所にする 13 coin.center = sender.location(in: self.view) 14 // 親ビュー(view)にサブビュー(coin)を追加して表示させる(実際に画面に表示するのはこの操作) 15 self.view.addSubview(coin) 16 } else if coinCount == 1 { 17 // 画像のビュー(coin)を親ビューから削除(unlink)する 18 coin.removeFromSuperview() 19 // 次の操作でも消えるが、登録した画像のビューは残ったままなのであまり良い操作ではないはず 20 // coin.image = nil 21 } // coinCount == 2 の時は何も起きない(条件判定がないため) 22 coinCount = coinCount + 1 23 coinCount = coinCount % 3 24 } 25 26 override func viewDidLoad() { 27 super.viewDidLoad() 28 // Do any additional setup after loading the view. 29 } 30}

追記

Xcode は変数のスコープを視覚的に確認できます(標準設定だと色が暗いのでわかりにくいのですが)。

確認したい変数にカーソルを合わせるだけで、同じスコープの変数すべて背景色が変わりますので、これで確認可能です。

イメージ説明

投稿2020/04/07 05:29

編集2020/04/07 07:15
TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

magiee

2020/04/07 07:07

非常に分かりやすい説明ありがとうございました。 スコープについて、知識としてはありましたが、実際に扱ってみないと分からないものですね。 本当に感謝しています。ありがとうございます。
TsukubaDepot

2020/04/07 07:15

Xcodeは標準でスコープを確認する機能が備わっていますので、それを併用するといいかもしれません。
magiee

2020/04/07 08:24

追記までしてくださりありがとうございます! 上記の画像ですと、coinのスコープが、coinCount==0の範囲内のみで、coinCount==1の範囲には無い。かつ、新たな変数を作っているので、同じ名前のcoin変数でも別の変数ということですね。 少しずつ、自分の目指しているアプリに近づいており、感謝しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問