「touchesBegan」の処理で「outletCollection」を使用したい
swiftで、画面をタップする毎に10個のImageViewの画像を順番に変更するシステムを作ろうとしています。
10個のImageViewは、全てOutletCollectionとして管理し、それぞれに違うtagつけています。(0~9)
※追記:処理は、UIViewのXibファイル上で行っています。
しかし、画面をタップするとそのOutletCollectionがnilであるとエラーが表示され、前に進めない状況です。
以下に詳しい状況を記載します。
発生している問題・エラーメッセージ
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
和訳:Thread 1: Fatal error: オプション値のアンラップ中に予期せずnilが見つかった
該当のソースコード
Swift
1//xibファイルになります。 2class AnimationView: UIView { 3 let data = [["画像ファイル名1","こんにちは"], 4 ["画像ファイル名2","こんばんは"]] //本来ある配列内のデータ数は省略 5 6 @IBOutlet var imageViews: [UIImageView]! 7 8 var tagNumber = 0 9 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 10 if tagNumber < 10 { 11 //↓「imageViewsがnilである」というエラーが発生。 12 for img in imageViews { 13 if img.tag == tagNumber { 14 img.image = UIImage(named: data[tagNumber][0]) 15 } 16 } 17 } 18 tagNumber += 1 19 } 20 21}
touchsBegan内でOutletCollectionを呼び出すと、上記のエラーが発生してしまいます。
一方で、override init(frame: CGRect)でOutletCollectionを呼び出す分にはしっかりと参照できてしまいます。
######処理が成功する例↓
swift
1 2let data = [["画像ファイル名1","こんにちは"], 3 ["画像ファイル名2","こんばんは"]] //本来ある配列内のデータ数は省略 4 5@IBOutlet var imageViews: [UIImageView]! 6 7override init(frame: CGRect) { 8 super.init(frame: frame) 9 10 //nilのエラーが出ることもなく、しっかりとfor文で処理を回すことができます。 11 for img in imageViews { 12 img.image = UIImage(named: data[img.tag][0]) 13 } 14 15 16 }
試したこと
touchesBegan内の処理を削除し、代わりに** print(imageViews) を記述 ←nilと出力される**
swift
1class AnimationView: UIView { 2 3 @IBOutlet var imageViews: [UIImageView]! 4 5 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 6 print(imageViews) //nil と出力される 7 } 8}
###※追記 省略していたコードの全体を記載します
swift
1class AnimationView: UIView { 2 3 @IBOutlet var imageViews: [UIImageView]! 4 5 // ガチャ結果のデータを呼び出す。 6 let data = [["画像ファイル名1","1"], 7 ["画像ファイル名2","2"], 8 ["画像ファイル名3","3"], 9 ["画像ファイル名4","4"], 10 ["画像ファイル名5","5"], 11 ["画像ファイル名6","6"], 12 ["画像ファイル名7","7"], 13 ["画像ファイル名8","8"], 14 ["画像ファイル名9","9"], 15 ["画像ファイル名10","10"],] 16 17 override init(frame: CGRect) { 18 super.init(frame: frame) 19 loadNib() 20 21 //ここではnilのエラーが出ることもなく、しっかりとfor文で処理を回すことができます。 22 for img in imageViews { 23 img.image = UIImage(named: data[img.tag][0]) 24 } 25 26 print(imageViews.count) //10 と出力される 27 } 28 29 required init(coder aDecoder: NSCoder) { 30 super.init(coder: aDecoder)! 31 } 32 33 func loadNib(){ 34 guard let view = UINib(nibName: "AnimationView", bundle: nil).instantiate(withOwner: self, options: nil).first as? AnimationView else { 35 return 36 } 37 view.frame = self.bounds 38 self.addSubview(view) 39 } 40 41 42 var tagNumber = 0 43 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 44 print(imageViews.count) //nil と出力される 45 if tagNumber < 10 { 46 //↓「imageViewsがnilである」というエラーが発生。 47 for img in imageViews { 48 if img.tag == tagNumber { 49 img.image = UIImage(named: data[tagNumber][0]) 50 } 51 } 52 } 53 tagNumber += 1 54 } 55} 56
補足情報(FW/ツールのバージョンなど)
ツール:**XCode Version 12.5 **
使用言語:Swift5
シミュレーター:iPhone11ProMax
回答1件
あなたの回答
tips
プレビュー