teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

別解を追記

2020/09/06 13:10

投稿

TsukubaDepot
TsukubaDepot

スコア5086

answer CHANGED
@@ -67,4 +67,97 @@
67
67
  nextimageview.image = UIImage(data: pngImage)
68
68
  }
69
69
  }
70
+ ```
71
+
72
+ ##追記
73
+
74
+ UserDefaults を使うとなると、まずはエラーが出ないようにする必要があります。
75
+ エラーのうち一つ目は、`Data`型を渡さなければいけないところに`Data?`型を渡していることが原因です。
76
+
77
+ が、そもそも使おうとしているメソッドが古く廃止予定のメソッドなので、現行(Swift5)のメソッドに合わせて書き換える必要があります。
78
+
79
+ ```Swift
80
+ import UIKit
81
+
82
+ class ViewController: UIViewController {
83
+ let defaults = UserDefaults.standard
84
+ let image = UIImage(named: "あつもり2")
85
+
86
+ @IBOutlet weak var imageview: UIImageView!
87
+ {
88
+ didSet
89
+ {
90
+ imageview.image = image
91
+ }
92
+ }
93
+
94
+ override func viewDidLoad() {
95
+ super.viewDidLoad()
96
+ // Do any additional setup after loading the view.
97
+ }
98
+
99
+ @IBAction func save(_ sender: Any) {
100
+ // Value of optional type 'UIImage?' must be unwrapped to a value of type 'UIImage'
101
+ // let pngImageData: Data? = UIImagePNGRepresentation(imageview.image)
102
+ let pngImageData = imageview.image?.pngData()
103
+ defaults.set(pngImageData, forKey: "画像キー")
104
+ }
105
+ }
106
+ ```
107
+
108
+ 一方、遷移先についてはこのような感じになります。
109
+ こちらは、取得するためのメソッド名が不足していることがエラーの原因です。
110
+
111
+ ```Swift
112
+ import UIKit
113
+
114
+ class nextViewController: UIViewController {
115
+ let defaults = UserDefaults.standard
116
+
117
+ @IBOutlet weak var nextimageview: UIImageView!
118
+ {
119
+ didSet
120
+ {
121
+ // Cannot call value of non-function type 'UserDefaults'
122
+ // let nextimage = UIImage(data: defaults(forKey: "画像キー"))
123
+ if let data = defaults.data(forKey: "画像キー") {
124
+ nextimageview.image = UIImage(data: data)
125
+ }
126
+ }
127
+ }
128
+
129
+ override func viewDidLoad() {
130
+ super.viewDidLoad()
131
+
132
+ // Do any additional setup after loading the view.
133
+ }
134
+ }
135
+ ```
136
+
137
+ しかし、実はこの方法ではうまく動きません。
138
+
139
+ というのは、`ViewController` の `save()`が実行される前に、`nextViewController` の `nextViewController` に設定しているプロパティオブザーバが作用し、画像が保存されていないのにデータを読み込もうとしてしまうためです。
140
+
141
+ 従って、`ImageView`に画像を設定するのは、`viewWillAppear()`以降によびだされるメソッド内でおこなうことになります。
142
+
143
+ ```Swift
144
+ import UIKit
145
+
146
+ class nextViewController: UIViewController {
147
+ let defaults = UserDefaults.standard
148
+
149
+ @IBOutlet weak var nextimageview: UIImageView!
150
+
151
+ override func viewDidLoad() {
152
+ super.viewDidLoad()
153
+ // Do any additional setup after loading the view.
154
+ }
155
+
156
+ override func viewWillAppear(_ animated: Bool) {
157
+ super.viewWillAppear(animated)
158
+ if let data = defaults.data(forKey: "画像キー") {
159
+ nextimageview.image = UIImage(data: data)
160
+ }
161
+ }
162
+ }
70
163
  ```