質問: saveImageArray[currentDrawNumber - 1] currentDrawNumber -= 1 } ``` この処理で画像を書き換えられるはずなのですが、上手くいきません。 教えて戴けませんか ?
回答: はじめまして。@OOPerさんが仰るとおり、クラス定義からクラス定義終了まで全てのコードが記述されていないので確実とは言えませんが、上のソースには > > タップされた座標にflowerを追加する(buttonをクリックした時の処理) > > > で、flowerという画像ファイルを`canvasView`に`addSubview`しています。 つまり、`canvasView`にオーバーレイしたViewを作成し、そこにflowerという名前の画像を表示している様に見えます。 しかし、 > > 配列にcanvasView.imageを保存 > > > で`saveImageArray`にバックアップしている`canvasView.image`は、上に記述されたソース断片ではなにもセットしていないので、空のイメージの可能性が高く 更に > > 保存している直前のimageに置き換える (undoボタンをクリツクした時の処理) > > > 以降で保存された画像をセットし直しているのは、`canvasView`の`image`プロパティを操作しているように見えます。 そうすると、 ---- flowerという最初にセットした画像 --------------------- = addされたSubview ----- バックアップした空のimageをUndoで再セットした画像 ----- = canvasView と言うことが起きているのではないでしょうか このため、undoボタンをクリックしたときの処理は実際に行われていても、 addされたSubviewの下に隠れて見えていない事が予想されます。 なので、 a. タップされた座標に〜 の部分で、`addSubview`せず、`canvasView`の`image`に画像をセットする ``` let flower = UIImage(named: "flower") // センタリング処理省略 canvasView.image = flower ``` b. Undoアクション の部分で、`addSubview`した`view`の`image`に画像をセットする(バックアップするイメージの取得元も`addSubview`した`view`の`image`プロパティにする) ``` // nはaddSubviewしたflowerのsubViewsから取得される順番 self.canvasView.subViews[n].image = saveImageArray[currentDrawNumber - 1] ``` または ``` // flowerが例示されたソースの通り、クラスのメンバー変数であれば // イメージのバックアップも書き戻しもflowerに対して行えばよい // 配列にcanvasView.imageを保存の部分 saveImageArray.append(flower.image!) // 保存している直前のimageに置き換えるの部分 flower.image = saveImageArray[currentDrawNumber - 1] ``` ただし、この場合、`let flower`は適切な変数名ではないので、クラス内全体を通して`flower`こそが実質的にキャンバスであると言うことが解る変数名に書き替えた方が間違いが少なくなると思います 以上より、a,bで例示したどちらか片方に統一すれば良いような気がします。 bの例示は2つ示しましたが、どちらか片方だけが必要で、両方の修正を行うと、また挙動がわからなくなります。 ただしbの解決方法は、「ではIBOUtletで宣言しているcanvasViewというImageViewは何のために存在しているか?」がわからない、必要のないオブジェクトになってしまうので、勝手な予測ながら「よくわからないけど、こうすれば動いた」以上の意味は無いのでは無いかと思います。 このため、a.で示した、IBOutlet宣言したcanvasViewに極力余計なViewをaddしない方針でプログラムの修正をし、どうしても質問に記述されていない部分が理由で`addSubview`する必要でない限り、b.の方針でプログラムを修正すべきではない様に思えます。