Unable to use ForEach loop on #Binding variable [closed] - swift

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I recently asked a question however it was removed as they thought the answer existed already and so I checked out this question. I have tried implementing the solution found here into my code and now run into a slightly different error.
Basically I am trying to create a simple application with a list of items that can be clicked on to navigate to a detail view with an edit feature. The data is read from a JSON file which is why the data is in a binding so it can be updated and this is not a problem anywhere else in the project.
import SwiftUI
struct EateryList: View {
#Binding var eateries: [Eatery]
var body: some View {
NavigationView {
VStack {
List {
ForEach(eateries.indicies, id: \.self) { i in
NavigationLink(destination: EateryDetail(eatery: $eateries[i])) { //errors appear here
EateryRow(eatery: $eateries[i])
}
}
}
.navigationTitle("Favourite Eateries")
.navigationBarItems(leading: EditButton(), trailing: Button( action: add)
{
Image(systemName: "plus")
}
)
.listStyle(InsetGroupedListStyle())
}
}
}
func add() {
eateries.append(Eatery(name: "Eatery", location: "Insert location here", notes: "Insert notes here", reviews: ["Insert reviews here"], url: "https://i.imgur.com/y3MMnba.png"))
}
}
I get 3 errors with this code currently which I do not fully understand...
Generic struct 'ForEach' requires that 'Binding' conform to 'RandomAccessCollection'
Referencing subscript 'subscript(dynamicMember:)' requires wrapper 'Binding<[Eatery]>'
Value of type '[Eatery]' has no dynamic member 'indicies' using key path from root type '[Eatery]'
All help is greatly appreciated right now and if you need further clarification of other parts of the project please let me know :)

It's a spelling mistake. It's indices not indicies
ForEach(eateries.indices, id: \.self) { i in //<-- Here
NavigationLink(destination: EateryDetail(eatery: $eateries[i])) {
EateryRow(eatery: $eateries[i])
}
}

Related

Does anyone know what this stack is called SwfitUI? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 months ago.
Improve this question
I'll keep it quick: Does anyone know if SwiftUI have a built in method that renders something like this image:
where the view just changes based on what label you tap? I wonder if it's possible to achieve this using some sort of navigation view or stack? I'd appreciate any input! Thanks.
EDIT:
HStack {
Picker(selection: $selected, label: Text("Mode"), content:{
Text("Projects").tag(1)
Text("Notes").tag(2)
Text("Docus").tag(3)
}).pickerStyle(SegmentedPickerStyle())
.frame(width: 200, height: 10)
.padding(EdgeInsets(top: 0, leading: 0, bottom: 10, trailing: -0))
if selected == 1 {
// how would i show another view if the user selects option 1?
}
}
This is a picker. to be precise, this is a segmented picker.
You can create it like so:
struct ContentView: View {
#State private var favoriteColor = 0
var body: some View {
Picker("What is your favorite color?", selection: $favoriteColor) {
Text("Red").tag(0)
Text("Green").tag(1)
Text("Blue").tag(2)
}
.pickerStyle(.segmented)
}
}
When we create the picker we pass in a binding (when we change the picker's value it will know to switch to it) this is the thing with the dollar sign ($)
The next thing is to add the segments.
So we add text views with a tag attached to each one.
Lastly we need to set the picker style (in this case the segmented)
.pickerStyle(.segmented)
I suggest you to look here: Create a segmented control and read values from it
Hope this helps!

How to persist state from a class into a separate SwiftUI view? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am having problems persisting a class's state into a SwiftUI struct's view.
I have a class that acts as a controller, defined in one file, and a SwiftUI view that is supposed to change according to properties in that controller.
I've defined these files as such:
ClockController.swift
class ClockController:ObservableObject {
#Binding var isAM:Bool
init(){
self.isAM = false
}
func toggleAMPM(){
self.isAM = !self.isAM
}
}
and TestUI.swift
struct TestUI:View{
#ObservedObject var clockController:ClockController = ClockController()
var body: some View {
Button(action: {
self.clockController.toggleAMPM()
}){
Text("Toggle")
}
Text(self.clockController.isAM ? "AM" : "PM")
}
}
I want the TestUI to change/re-render every time the self.clockController.isAM variable changes (when the toggle button is pressed), which is why I have made ClockController an ObservableObject and added the #Binding keyword to the isAM property. However, I keep getting the following errors with this setup on ClockController's initializer method:
'self' used in property access 'isAM' before all stored properties are initialized and Return from initializer without initializing all stored properties
How can I get my TestUI to bind on ClockController's isAM variable?
all! I've fixed the problem myself. I needed to remove the #Binding keyword from ClockController's isAM property and change it to #Published. That did the trick.
Kudo's to YouTube and this video: https://youtu.be/-yjKAb0Pj60?t=919

NavigationLink syntax

I'm trying to learn SwiftUI and Swift in general so I'm a total newbie here. I started by reading docs on Swift Language, making a console app and playing around with a bunch of concepts of the language there. Then I tried SwiftUI and immediately I see a bunch of syntax that wasn't documented in the language itself.
So I dug around some more and I see there is a bunch of compiler and language magic going on behind the scenes which makes the syntax I see in SwiftUI work. A lot of the magic maybe isn't so well documented. So I dug around and found answers to most of my questions about the SwiftUI syntax I'm seeing. Except this:
NavigationView{
VStack {
Text("Select your device")
List{
NavigationLink{
SensorView()
} label:{
Text("Raspberry Pi Zero")
}
}
}
What is with the label: statement outside of the curly braces for the NavigationLink closure all about? I can see in my app that it creates a label in the NavigationLink but I don't understand why the label: is outside of the curly braces where it looks to me to be more or less detached from the NavigationLink it is seemingly associated with? I'm trying to understand this so I will know when/where to apply this pattern. I copied the code above from someone else's sample.
Any insighgts or teachings would be appreciated.
This new syntax is part of Multiple Trailing Closures, which was released recently. Let's look at your NavigationLink initializer:
init(destination: () -> Destination, label: () -> Label)
Here, there's 2 parameters that take in closures: destination and label. So, that means you can write it like this (the plain, normal way):
NavigationLink(destination: {
Text("The destination")
}, label: {
Text("Click me!")
})
Or this, via trailing closure syntax:
NavigationLink(destination: {
Text("The destination")
}) {
Text("Click me!")
}
Or what you did in your question. Note: when you have multiple trailing closures, you need to add the argument label (for example label:) for all closures after the first.
NavigationLink {
Text("The destination")
} label: {
Text("Click me!")
}

SwiftUI Group{} Nested in VStack{} Throwing Errors

I am receiving two errors whenever I attempt to add a Group struct to the VStack struct. The first error is on line 5 VStack { and reads:
Static method 'buildBlock' requires that 'Group' conform to 'View'
The second error is on line 6 Group { and reads:
Missing arguments for parameters 'id', 'label' in call
Here is the complete code for the view file:
import SwiftUI
struct FailTest: View {
var body: some View {
VStack {
Group {
Text("1")
Text("2")
Text("3")
Text("4")
Text("5")
Text("6")
Text("7")
Text("8")
Text("9")
Text("10")
}
Text("11")
}
}
Any idea why this is throwing these two errors? The code is based on multiple examples I have found online, as well as two books.
I cannot reproduce this problem using just the code you've provided (plus a trailing brace that this seems to be missing, suggesting this might not be precisely all the code in the fille). I suspect you other code in the project, possibly another definition of Group that is causing the problem. I recommend moving just this code into a Playground to explore.
I'm testing with the latest Xcode 11.5 GA build, in case that is a difference.

Ambiguous reference with a Picker in Swift UI

I'm trying to make a Picker with SwiftUI. I've follow a tutorial but don't have the same result. There is Ambiguous reference on the self.category.count and self.category[$0]. After one entire day, I still don't know how to fix it ...
import SwiftUI
struct Picker : View {
var category = ["Aucun", "BF Glaive", "Baguette", "Negatron", "Larme", "Ceinture", "Arc", "Cotte", "Spatule"]
#State private var selectedCategory = 0
var body: some View {
VStack {
Picker(selection: $selectedCategory, label: Text("Item")) {
ForEach(0 ..< self.category.count) {
Text(self.category[$0])
.tag($0)
}
}
Text("Selected : \(category[selectedCategory])")
}
}
}
To resolve name conflicts between modules, you can either:
Rename your Picker to something else.
Use the qualified (full) name:
SwiftUI.Picker(selection: $selectedCategory, label: Text("Item")) {
The error message Ambiguous reference to member 'count’ is misleading. What you have is a naming conflict between SwiftUI.Picker and your Picker struct. Just change the name of your struct to something other than Picker. For example:
struct CategoryPicker : View {
// ...
}
Alternatively, you can resolve the naming conflict between the modules by providing the fully qualified name for SwiftUI.Picker (as Sulthan pointed out):
SwiftUI.Picker(selection: $selectedCategory, label: Text("Item")) {
// ...
}
However, I wouldn’t advise this option unless your intention is to replace SwiftUI.Picker everywhere in your app. Your code includes the category array and a Text view, so it's unlikely this is what you're after.
If the app eventually needs OtherPicker with a SwiftUI.Picker and the module name is omitted again, it’ll be even more confusing to track down the error—and you’ve already spent an “entire day” on it. So, best to avoid this possibility by not introducing the conflict at all :)