回答編集履歴
1
ソースコードを追記しました。
test
CHANGED
@@ -125,3 +125,171 @@
|
|
125
125
|
}
|
126
126
|
```
|
127
127
|
|
128
|
+
### 追記です。
|
129
|
+
|
130
|
+
コードの修正ありがとうございます。
|
131
|
+
再現確認できました。
|
132
|
+
|
133
|
+
原因がわかりました。
|
134
|
+
`self.listVM = ListViewModel(gearList: gearList)` でlistVMを設定していますが、
|
135
|
+
この方法では@Stateとしてちゃんと設定されていないことになるみたいです。
|
136
|
+
|
137
|
+
次のリンク先の「イニシャライザで値を設定する場合」を見てみると良いと思います。
|
138
|
+
[【SwiftUI】@Stateの使い方 | カピ通信](https://capibara1969.com/1608/#toc5)
|
139
|
+
|
140
|
+
ListViewModelのイニシャライザと、
|
141
|
+
listVMの初期値は不要になりそうですね。
|
142
|
+
|
143
|
+
修正したコードです。
|
144
|
+
修正ポイントに`// ***`のようなコメントを入れましたので、見てみてください。
|
145
|
+
|
146
|
+
```swift
|
147
|
+
// ContentView.swift
|
148
|
+
import SwiftUI
|
149
|
+
struct ContentView: View {
|
150
|
+
let gearList =
|
151
|
+
GearList(
|
152
|
+
gearlistid: "gearlistid",
|
153
|
+
listname: "gearlistname",
|
154
|
+
lengthofstay: "2day",
|
155
|
+
howtostay: "Hotel",
|
156
|
+
startdate: Date(),
|
157
|
+
baseweight: 100,
|
158
|
+
consumableweight: 100,
|
159
|
+
wornweight: 100,
|
160
|
+
totalweight: 300
|
161
|
+
)
|
162
|
+
var body: some View {
|
163
|
+
ListView(gearList: gearList)
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
#Preview {
|
168
|
+
ContentView()
|
169
|
+
}
|
170
|
+
|
171
|
+
|
172
|
+
// Item.swift
|
173
|
+
import Foundation
|
174
|
+
struct Item: Codable, Identifiable, Hashable {
|
175
|
+
var id: String?
|
176
|
+
var brandid: String
|
177
|
+
var brandname: String
|
178
|
+
var categoryid: Int
|
179
|
+
var categoryname: String
|
180
|
+
var createdAt: Date
|
181
|
+
var itemid: String
|
182
|
+
var memo: String
|
183
|
+
var name: String
|
184
|
+
var subcategoryid: Int
|
185
|
+
var subcategoryname: String
|
186
|
+
var updatedAt: Date
|
187
|
+
}
|
188
|
+
|
189
|
+
// GearList.swift
|
190
|
+
import Foundation
|
191
|
+
struct GearList: Codable, Identifiable, Hashable {
|
192
|
+
var id: String?
|
193
|
+
var gearlistid : String
|
194
|
+
var listname : String
|
195
|
+
var lengthofstay : String
|
196
|
+
var howtostay : String
|
197
|
+
var startdate : Date
|
198
|
+
var baseweight : Int
|
199
|
+
var consumableweight : Int
|
200
|
+
var wornweight : Int
|
201
|
+
var totalweight : Int
|
202
|
+
}
|
203
|
+
|
204
|
+
|
205
|
+
// ItemService.swift
|
206
|
+
import Foundation
|
207
|
+
struct ItemService {
|
208
|
+
func readItems(gearList:GearList, completion: @escaping([Item]) -> Void) {
|
209
|
+
let items: [Item] = [
|
210
|
+
Item(brandid: "brandid",
|
211
|
+
brandname: "brandname",
|
212
|
+
categoryid: 11,
|
213
|
+
categoryname: "categoryname",
|
214
|
+
createdAt: Date(),
|
215
|
+
itemid: "itemid",
|
216
|
+
memo: "memo",
|
217
|
+
name: "name\(Int.random(in: 0..<100))",
|
218
|
+
subcategoryid: 12,
|
219
|
+
subcategoryname: "subcategoryname",
|
220
|
+
updatedAt: Date()),
|
221
|
+
Item(brandid: "brandid",
|
222
|
+
brandname: "brandname",
|
223
|
+
categoryid: 11,
|
224
|
+
categoryname: "categoryname",
|
225
|
+
createdAt: Date(),
|
226
|
+
itemid: "itemid",
|
227
|
+
memo: "memo",
|
228
|
+
name: "name\(Int.random(in: 0..<100))",
|
229
|
+
subcategoryid: 12,
|
230
|
+
subcategoryname: "subcategoryname",
|
231
|
+
updatedAt: Date()),
|
232
|
+
]
|
233
|
+
completion(items)
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
// ListViewModel.swift
|
238
|
+
import Foundation
|
239
|
+
import Observation
|
240
|
+
|
241
|
+
@Observable class ListViewModel {
|
242
|
+
private let itemservice = ItemService()
|
243
|
+
private var gearList : GearList
|
244
|
+
var listData: [[Item]] = []
|
245
|
+
// *** init()コメントアウト
|
246
|
+
// init() {
|
247
|
+
// print("init")
|
248
|
+
// self.gearList = GearList(gearlistid: "", listname: "", lengthofstay: "", howtostay: "", startdate: Date(), baseweight: 0, consumableweight: 0, wornweight: 0, totalweight: 0)
|
249
|
+
// }
|
250
|
+
init(gearList:GearList) {
|
251
|
+
self.gearList = gearList
|
252
|
+
readAndSortItems(gearList:gearList)
|
253
|
+
}
|
254
|
+
func readAndSortItems(gearList:GearList) -> Void {
|
255
|
+
listData = []
|
256
|
+
itemservice.readItems(gearList:gearList) { item in
|
257
|
+
print("completion")
|
258
|
+
self.listData.append(item)
|
259
|
+
}
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
|
264
|
+
// ListView.swift
|
265
|
+
import SwiftUI
|
266
|
+
import Observation
|
267
|
+
struct ListView: View {
|
268
|
+
var gearList: GearList
|
269
|
+
// *** 初期値なし
|
270
|
+
@State private var listVM: ListViewModel
|
271
|
+
|
272
|
+
init(gearList: GearList) {
|
273
|
+
self.gearList = gearList
|
274
|
+
// *** @Stateをinit()で設定する場合は少し特殊な記述になります。
|
275
|
+
_listVM = State(initialValue: ListViewModel(gearList: gearList))
|
276
|
+
}
|
277
|
+
|
278
|
+
var body: some View {
|
279
|
+
Button("tap", action: action)
|
280
|
+
List {
|
281
|
+
ForEach(listVM.listData.indices, id: \.self) { index in
|
282
|
+
Section(header:Text(listVM.listData[index][0].categoryname)) {
|
283
|
+
ForEach(listVM.listData[index].indices, id: \.self) { index2 in
|
284
|
+
Text(listVM.listData[index][index2].name)
|
285
|
+
}
|
286
|
+
}
|
287
|
+
}
|
288
|
+
}
|
289
|
+
}
|
290
|
+
func action() {
|
291
|
+
listVM.readAndSortItems(gearList: gearList)
|
292
|
+
}
|
293
|
+
}
|
294
|
+
```
|
295
|
+
|