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

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

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

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

Swift

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

Q&A

解決済

1回答

1171閲覧

画面を閉じて再度開いたとき,Viewを閉じる前と同じ配置にしたいです.

ponponpoo

総合スコア1

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/07/11 14:53

編集2020/07/12 02:52

前提・実現したいこと

画面AとBがあるとします.
画面Aはメニュー画面で,画面Bへ遷移するボタンがあります.
画面Bでは,画像にスタンプを貼り付けるような編集作業ができます.

画面Bで編集し終えた後,画面Aに戻り,また画面Bを開いたら,
編集していた画面に戻したいです.

スタンプは画面BにaddViewされており,戻ってきたときにも
また動かせるようにしたいので,一括画像保存とかではありません.

addViewされたViewの座標を配列かなにかで保存すれば
いいのかなと考えておりますが,もっとスマートなやり方はないでしょうか.

また,座標を保存する際に,いい感じのメソッドがあれば教えていただきたいです.
今のところは,frameが使えそうだと考えております.

よろしくおねがいします.



追記

画面AからBへはpresent()を使用しています.
画面Bは全画面表示なので画面BはAの子供となるのでしょうか?

画面Bはだいたい以下の構造です.(本当は下のContainerViewを変えるボタンがあります)
CollectionViewには,スタンプの画像一覧が表示されます.
イメージ

ContainerViewの中身は切り替えができます.
そこのところは,こちらを参考にしました.

動作イメージは,
Cellに表示されているスタンプ(Cell)を長押し → スタンプが手の動きに合わせて移動(Cellの画像を複製) → ImageViewに持っていく → 貼り付ける

貼り付けたものを長押し → スタンプを移動

といった具合です.

BVCは,ContainerViewの表示を切り替えるものが記述されています.
(上リンク)

CVCでは
① 長押しでCellの画像を複製,画像移動のために,ロングプレスとパンを設定

Swift

1 func setGesture() { 2 //長押しをセット 3 let longPressGesture = 4 UILongPressGestureRecognizer(target: self, 5 action: #selector(self.longPress(_:))) 6 longPressGesture.delegate = self 7 8 //パンをセット 9 let panGesture = UIPanGestureRecognizer(target: self, action: #selector(HGotItemViewController.panView(sender:))) 10 panGesture.delegate = self 11 12 self.collectionView.addGestureRecognizer(longPressGesture) 13 self.collectionView.addGestureRecognizer(panGesture) 14 15 }

② Cellを長押しされたらCell内の画像のUIImageViewを作る

Swift

1 2 @objc func longPress(_ sender: UILongPressGestureRecognizer){ 3 if sender.state == .began { 4 5 //押された座標とCell番号 6 newTapPoint = sender.location(in: view) 7 tapPoint = sender.location(in: view) 8 let indexPath = self.collectionView.indexPathForItem(at: tapPoint) 9 10 if indexPath != nil{ 11 //indexPathからアイテムの画像を判断 12 itemImage = (UIImage(named: "item/(indexPath!.row)")?.withRenderingMode(.alwaysTemplate))! 13 14//追加するViewが手の位置にくるように設定 15 stampView = UIImageView(frame: CGRect(x: tapPoint.x,y: tapPoint.y, width: 168, height: 90)) 16 stampView.backgroundColor = .red 17 stampView.center = CGPoint(x:tapPoint.x+470,y:tapPoint.y) 18 stampView.image = itemColorImage 19 20//追加したあとも位置を変えられるように長押しとパンを設定 21 22 let longPressGesture2 = 23 UILongPressGestureRecognizer(target: self, 24 action: #selector (self.move(_:))) 25 longPressGesture2.delegate = self 26 stampView.addGestureRecognizer(longPressGesture2) 27 28 let panGesture2 = UIPanGestureRecognizer(target: self, action: #selector(self.panView(sender:))) 29 panGesture2.delegate = self 30 stampView.addGestureRecognizer(panGesture2) 31 32 stampView.isUserInteractionEnabled = true 33 34 //Viewを追加 35 self.parent?.view.addSubview(stampView) 36 } 37 }else if sender.state == .ended{ 38 39 //画像以外のところに載せたら消す 40 if imageView.frame.contains(endPoint){ 41 print("endPoint=",endPoint) 42 }else{ 43 stampView.removeFromSuperview() 44 } 45 } 46 } 47 48 }

を行っています.

データの永続化もしたいです.
画面Aに戻った,アプリを落としたあとも,画面Bにくると編集していた画面を
表示させたいです.
永続化方法については,userDefaultsを使用しようと考えていますが,
初心者のため,何もわからず,データもそんな大きくならないと思うので
とりあえず検索して出てきたこれにしよう程度のです.
なので,もし,他に良い方法があれば教えて下さい.

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/07/11 15:41 編集

画面Aと画面Bの関係、遷移の方法が把握できません。 また、対象はgestureRecognizerが設定してあるViewでしょうが、addSubviewするものの条件によってはframeを保存する以外の方法がよりベターである可能性があります。 以前と同じような不毛なやり取りはしたくありませんので、コードを提示してください。 よりよい回答がつく可能性が高くなります。 加えて、データの永続化が必要となるようでしたらその旨並びに永続化方法も記載されると良いと思います。
guest

回答1

0

ベストアンサー

Reflectionsubviewsで取得して、値渡しなどしていないようなのでライフサイクルにそって保存、読み込みすればよいかと思います。

subviewsからUILabeltextframeを保存してみました。読み込んだ情報から復元できると思います。

動かす場合はStoryboardにUILabelとか適当に貼り付けてください。

質問のケースではUIImageViewのようですが、UIImageViewをそのまま保存して、戻してgestureRecognizerなどがそのまま動くかなど試してみてもいいかもしれなせん。

swift

1import UIKit 2 3class ViewController: UIViewController { 4 5 override func viewDidAppear(_ animated: Bool) { 6 super.viewDidAppear(animated) 7 // ユーザーデフォルトから取得 8 let labels = UserDefaults.standard.decodedObject(Labels.self, forKey: "KEY") 9 dump(labels) 10 } 11 12 override func viewWillDisappear(_ animated: Bool) { 13 super.viewWillDisappear(animated) 14 15 let labels = Labels() 16 // self.viewのサブビューのうちラベルの値を取得する 17 self.view.subviews.forEach { 18 if let label = $0 as? UILabel { 19 let l = LabelProperties(text: label.text ?? "", frame: label.frame) 20 labels.labelProperties.append(l) 21 } 22 } 23 dump(labels) 24 // ユーザーデフォルトに保存 25 UserDefaults.standard.setEncoded(labels, forKey: "KEY") 26 } 27 28} 29 30class Labels: Codable { 31 var labelProperties = [LabelProperties]() 32} 33 34class LabelProperties: Codable { 35 36 let text: String 37 let frame: CGRect 38 39 init(text: String, frame: CGRect) { 40 self.text = text 41 self.frame = frame 42 } 43} 44 45 46// https://teratail.com/questions/274938#reply-392168 をコピペ 47// MasakiHoriさんありがとうございます。 48extension UserDefaults { 49 func setEncoded<T: Encodable>(_ value: T, forKey key: String) { 50 guard let data = try? JSONEncoder().encode(value) else { 51 print("Can not Encode to JSON.") 52 return 53 } 54 55 set(data, forKey: key) 56 } 57 58 func decodedObject<T: Decodable>(_ type: T.Type, forKey key: String) -> T? { 59 guard let data = data(forKey: key) else { 60 return nil 61 } 62 63 return try? JSONDecoder().decode(type, from: data) 64 } 65} 66

投稿2020/07/12 21:53

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ponponpoo

2020/08/20 07:11

回答ありがとうございます. 無事に保存することができました. ですが,色と画像が保存できないので,別のページでまた質問させて頂きます.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問