ForEach(lessons) { lesson in ...}
is not a "normal" for loop. It is a View that needs to have other Views in it, not procedural code like you have.
Put this type of code (using a "normal" for loop`), for example in
.onAppear{
lessons.forEach{ lesson in ...}
}
Note that NavigationView is deprecated, use NavigationStack instead.
Post
Replies
Boosts
Views
Activity
If you cannot import Observation or import SwiftData it's because
you do not have the required environment/target settings,
such as target iOS 17, macOS 14. As mentioned
in the comments in your StackOverflow question.
Use .sheet(item: ...) instead, or capture the variable, like .sheet(isPresented: $isEditPresented) { [cardIndex] in ...}. Note, no need for @State in your EditCardView
Use .sheet(item: ...) instead, or capture the variable, like .sheet(isPresented: self.$showSheet) { [selectedItem] in ...}
Also you should have "@Published var items : [Item] = []" note, NO s in "[Item]". Conversely,
in your delete, use "items.remove(at: index)"
If you have @StateObject var items: ItemModel = .init() in your ContentView,
you should pass this model to the other views, for example @ObservedObject var items: ItemModel
in your ItemView.
Also you should have in your Observable class, items.append(Item(id: id, category: [category], image: image))
not Piercing(...).
Currently you create a new and different ItemModel every time you show ItemView
try using "struct ValueWrapper { var value = true } " instead of nesting "ObservableObject". Assuming you have declared "@StateObject var viewModel = ViewModel()" in
the ContentView parent.
use TextField("Age", value: $model.age, formatter: nf). See the docs for the differences between the two versions, TextField, in particular the text version does not take a formatter
With the first method you are changing the checkItems array directly using the index and all works well, but
using an index is not a recommended way.
To achieve the same with the second (preferred) method, you need to have a binding for the item to be able to change it.
To have that, use
ForEach($checkItems) { $item in ....}
You could use the ObservableObject directly, there is no need for anything else, it is made to be use like in this example code:
struct ContentView: View {
var body: some View {
BottomSheetView()
}
}
class Movie: ObservableObject{
@Published var name: String = ""
@Published var director: String = ""
@Published var stars: Double = 0.0
@Published var review: String = ""
// no need for all the functions
}
struct BottomSheetView:View{
@StateObject var newMovie = Movie()
var body: some View {
VStack(alignment: .leading) {
Text("Add Movie")
.fontWeight(.bold)
.font(.system(size:30))
.padding()
TextField("Movie name", text: $newMovie.name) // <--- here, etc...
TextField("Movie director", text: $newMovie.director)
// for testing, print to the console
Button("show me") {
print("\n---> newMovie: \(newMovie.name) \(newMovie.director) \n")
}
}
}
}
Try this code, works for me.
struct ContentView: View {
@State private var results = [DictionaryWord]()
var body: some View {
VStack {
Text("API Example iOS Application")
List(results) { item in
VStack(alignment: .leading) {
Text(item.word).font(.headline)
ForEach(item.phonetics) { phone in // <--- here
if phone.text != nil {
Text(phone.text!)
}
}
}
}
}
.task {
await loadData()
}
}
let freeDictionaryURL = "https://api.dictionaryapi.dev/api/v2/entries/en/hello"
func loadData() async {
guard let url = URL(string: freeDictionaryURL) else {
print("Invalid URL")
return
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
// --- here
let decoded: [DictionaryWord] = try JSONDecoder().decode([DictionaryWord].self, from: data)
results = decoded
} catch {
print(error) // <--- important
}
}
}
struct DictionaryWord: Identifiable, Codable { // <--- here
let id = UUID()
let word: String
let phonetics: [Phonetic]
let meanings: [Meaning]
let license: License
let sourceUrls: [String]
enum CodingKeys: String, CodingKey {
case word, phonetics, meanings, license, sourceUrls
}
}
struct License: Codable {
let name: String
let url: String
}
struct Meaning: Codable {
let partOfSpeech: String
let definitions: [Definition]
let synonyms, antonyms: [String]?
}
struct Definition: Codable {
let definition: String
let synonyms, antonyms: [String]?
let example: String?
}
struct Phonetic: Identifiable, Codable { // <--- here
let id = UUID()
let audio: String
let sourceURL: String?
let license: License?
let text: String?
enum CodingKeys: String, CodingKey {
case audio
case sourceURL = "sourceUrl"
case license, text
}
}
deleted comment
try adding .navigationViewStyle(.stack) to your NavigationView
deleted
Make your getHomeItems() with a closure when done, and
try something like this:
.onAppear {
self.showLoading = true
DispatchQueue.main.async {
store.getHomeItems() { _ in // <--- here
self.showloading = false // <--- here
}
}
...
}