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

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

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

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

Swift

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

Q&A

1回答

2998閲覧

SwiftUI 設定内容の表示と画面遷移して編集する機能 で編集内容が反映されない

msoniku

総合スコア36

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/08/13 09:06

編集2020/08/13 09:10

前提・実現したいこと

SwiftUIにてUser名と開始日終了日を登録し、確認可能な機能を実装しています。

ローカルに全ての情報を保持して、表示・編集・保存を行うことで実現できるかと思い、
以下の3つの構造体を実装しましたがうまく動作しません。

  1. 登録した名前と日付を表示する ContentViewのstruct
  2. 名前と日付をのデータを保持するProfileのstruct
  3. Profileを編集するProfileEditor

どなたかご助言いただけると助かります。

問題の概要

2,3の編集がうまく行きません。
初期値として登録した名前と日付のまま変更しても反映されない状態です。
また、1の日付をタップすると3の編集画面に遷移して編集、1の画面に反映するようにしたいのですが、1の日付のブロックのみが遷移して編集画面になってしまいます(加えて変更内容は反映されません、、、)

試したこと

  1. 登録した名前と日付を表示する ContentViewのstruct

 NavigationViewとNavigationLinkを使って編集画面へ遷移するように実装
NavigationLinkで変更したprofileを表示

2. 名前と日付をのデータを保持するProfileのstruct
名前と日付を用意
*SwiftUI tutorialを参考
https://developer.apple.com/tutorials/swiftui/working-with-ui-controls

3. Profileを編集するProfileEditor
TextFieldとDatePickerを使って編集できるように実装

機能の流れ
まず1の画面が表示されて、日付の部分をタップすると3の画面に遷移し、3の画面上で日付と名前を編集すると2の内容が変わり、1に戻ると編集した内容が反映されているような機能をイメージしています。

該当のソースコード

swift

1 2import SwiftUI 3 4// 1. 登録した名前と日付を表示する 5struct ContentView: View { 6 @State var val:Date = Date() 7 let f = DateFormatter() 8 9 init(){ 10 f.timeStyle = .none 11 f.dateStyle = .full 12 f.locale = Locale(identifier: "jp_JP") 13 } 14 15 var body: some View { 16 VStack { 17 // タイトル 18 Group{ 19 Text("日程計画").font(.largeTitle) 20 Divider() 21 } 22 // ユーザーイメージ 23 Group{ 24 HStack { 25 CircleImage(image:Image("Steve_Jobs")) 26 CircleImage(image:Image("Iron_Mask")) 27 CircleImage(image:Image("Denzel_Washington")) 28 } 29 Divider() 30 } 31 32 // 画面遷移 日程を入力可能 できればカレンダーで 33 Group{ 34 NavigationView{ 35 NavigationLink(destination:ProfileEditor(profile: .constant(.default))){ 36 Text(f.string(from: self.val)) 37 } 38 } 39 HStack{ 40 Text("日程") 41 Text(f.string(from: val)) 42 } 43 Divider() 44 } 45 46 // 画面遷移3 ユーザーごとメモをそれぞれ表示 47       // ***省略*** 48 } 49 } 50} 51 52 53// 2.名前と日付のデータを保持する 54import Foundation 55 56struct Profile { 57 var username: String 58 var startDate: Date 59 var endDate: Date 60 61 static let `default` = Self(username: "none") 62 63 init(username: String) { 64 self.username = username 65 self.startDate = Date() 66 self.endDate = Date() 67 } 68} 69 70 71// 3.Profileの編集を行う 72struct ProfileEditor: View { 73 @Binding var profile: Profile //user’s profileの値を引き継ぐ 74 75 var dateRange: ClosedRange<Date>{ 76 let min = Calendar.current.date(byAdding: .year, value: -1, to: profile.startDate)! 77 let max = Calendar.current.date(byAdding: .year, value: 1, to: profile.startDate)! 78 return min...max 79 } 80 81 var body: some View { 82 Form { 83 List{ 84 // ユーザー名 85 HStack { 86 Text("User Name").bold() 87 Divider() 88 TextField("USER NAME", text: $profile.username) 89 } 90 91 // 開始日時選択 92 VStack(alignment: .leading, spacing: 20) { 93 Text("Start Date").bold() 94 95 DatePicker( 96 "Start Date", 97 selection: $profile.startDate, 98 in: dateRange, 99 displayedComponents: .date 100 ).labelsHidden() 101 } 102 .padding(.top) 103 104 // 終了日時選択 105 VStack(alignment: .leading, spacing: 20) { 106 Text("End Date").bold() 107 DatePicker( 108 "Start Date", 109 selection: $profile.endDate, 110 in: dateRange, 111 displayedComponents: .date 112 ).labelsHidden() 113 } 114 .padding(.top) 115 } 116 } 117 } 118} 119

補足情報

Xcode Version 11.5
Swift version 5.2.4

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

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

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

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

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

guest

回答1

0

@Bindingと@Stateの使い方を理解することで反映されない問題を解決

以下備忘録
そもそもStruct間でプロパティを同期させるには@Bindingと@Stractの使い方をりかいしていないことが問題だった。

  • 親となるStructにて@Stateで設定したプロパティについて子Structでも引き継いで処理する
  • 子Structにおいて宣言時には@Bindingと型(String)を設定
  • 親Struct内でコストストラクトの引数に対象のプロパティを与えるときは$を頭につけるのが要注意
  • 子Struct内ではself.~で呼び出し可能

以下実験用コード

swift

1 2import SwiftUI 3 4struct StateandBinding_test: View { 5 6 @State var placeholder = "I am a placeholder." 7 8 var body: some View { 9 10 VStack{ 11 Text("(self.placeholder)") 12 13 CustomBotton(placeholder: self.$placeholder) 14 CustomBotton2(placeholder: self.$placeholder) 15 } 16 } 17} 18 19struct CustomBotton: View { 20 @Binding var placeholder: String 21 22 var body: some View{ 23 Button("cat says"){ 24 self.placeholder = "Merooow" 25 } 26 } 27} 28 29struct CustomBotton2: View { 30 @Binding var placeholder: String 31 32 var body: some View{ 33 Button("dog says"){ 34 self.placeholder = "Wooof" 35 } 36 } 37} 38 39 40struct StateandBinding_test_Previews: PreviewProvider { 41 static var previews: some View { 42 StateandBinding_test() 43 } 44} 45

投稿2020/08/14 07:25

msoniku

総合スコア36

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問