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
}
}
Post not yet marked as solved
try adding .navigationViewStyle(.stack) to your NavigationView
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
}
}
...
}
Post not yet marked as solved
adding .frame(height: 60) to each VStack works for me on macos 12.1 beta.
Post not yet marked as solved
Your code seems to work for me on macos 12.1beta, xcode 13.1,
targets ios 15 and MacCatalyst macos 12. Tested on real devices, iPad and Mac. Here is my test code:
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
List {
NavigationLink(destination: ExploreView()) {
Label("Explore", systemImage: "rectangle.3.group")
}
NavigationLink(destination: Text("ListView")) { // <-- for testing
Label("Devices", systemImage: "list.bullet.below.rectangle")
}
}
.listStyle(.sidebar)
.navigationTitle("Orchard")
ExploreView()
}
}
}
// for testing
struct ExploreView: View {
var body: some View {
ZStack {
Color.pink.ignoresSafeArea()
Label("Devices", systemImage: "list.bullet.below.rectangle").foregroundColor(.white)
}
}
}
add .multilineTextAlignment(.leading) to your VStack or Text(...)
Post not yet marked as solved
As a simple workaround, you could try this:
struct DecimalBindingView: View {
@State private var txt = ""
....
TextField("Input a number of type decimal…", text: $txt)
.onChange(of: txt) { val in
if let dec = Double(val) {
model.decimalQuantity = Decimal(dec)
}
}
...
}
Post not yet marked as solved
you could try something simple like this:
struct ContentView: View {
@State private var buttons = 0
var body: some View {
// the button to add other buttons
Button(action: { buttons += 1 } ) {
Image(systemName: "plus.circle.fill").foregroundColor(.black)
}
// the added buttons
ForEach(0..<buttons, id: \.self) { i in
Button("button \(i)") {
}
}
}
}
it's called a NavigationLink and it works inside a NavigationView. Look it up on the docs for how to use it.
you could even just do this:
TextField("Sort Order", text: Binding(
get: { (account.sortOrder != nil) ? String(account.sortOrder!) : "" },
set: { account.sortOrder = Int64($0.filter { "0123456789".contains($0) }) })
)
you could try something like this:
TextField("Sort Order",
text: Binding(
get: { (account.sortOrder != nil) ? String(account.sortOrder!) : "" },
set: {
if "0123456789".contains($0), let theInt = Int64($0) {
account.sortOrder = theInt
} else if $0.isEmpty { account.sortOrder = nil }
}
)
)