Ambiguous reference with a Picker in Swift UI - picker

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 :)

Related

iOS 16 bug or incorrect way to be changing #State property

One of my packages that I maintain uses editingChanged on TextField() to detect when the field is actually focused and then modify the text. This has worked fine on other iOS versions but in iOS16 it doesn't seem you're able to update a value from within a TextField if it's being used by that TextField
Is this the wrong way to update an #State property and it was bugged before 16 or is this something that was bugged in 16? If it's bugged, no big deal... but if I'm doing something wrong, of course I would like to fix that.
Below is a simplified version of what my package does, remember this was working before 16. You can even load it into a 15.5 sim and a 16 sim and see the difference.
#State private var text = ""
var body: some View {
Form {
TextField("", text: $text) { editingChanged in
text = "Should update text, but doesn't."
}
Button(action: {
text = "This will update without issue."
}) {
Text("Manually update via button.")
}
}
}
Try to use the following:
TextField("", text: $text)
.onChange(of: text) {
text = "should work now"
}

Redux conform Bindable for SwiftUI 2.0

I've been implementing Redux in my SwiftUI Project successfully but struggle when it comes to handling bindings properly. I want to use the binding functionality of SwiftUI while also storing the information in the Redux State.
As you see this kind of contradicts itself since the state can't be bound two-way.
This is my current code
#State var tab: Tab = .tab1
TabView(selection: $tab) { ... }
Ideally it should be comfortably usable like this if it's possible. I am also open to other ideas, that's just what i initially came up with - it's far from perfect.
#State var store = ReduxStore(...)
TabView(selection: $store.state.tab) { ... }
I figured out how to handle such cases. The solution for me is a Binding like:
let tabBinding = Binding<Tab> (
get: { self.store.state.currentTab }, // return the value from the state
set: { self.store.dispatch(action: NavigationAction.updateTab(tab: $0)) } // send the action here
)
Although this probably could be beautified it works, is pretty straight forward and solves the problem of working with Bindings in Redux.

Pass image name to custom Image subclass in SwiftUI

I am trying to accomplish something that looks pretty simple: I have a custom Image subclass in SwiftUI which I’m using for convenience, and I would like to use it in my app. My end goal is to use the OnboardingThumbnailImage in other views and simply pass an image name to the constructor.
import SwiftUI
struct OnboardingThumbnailImage: View {
var imageName: String
var body: some View {
Image(imageName)
.resizable()
.scaledToFit()
.frame(width: 50, height: 50)
.foregroundColor(Colors.tintColor)
}
}
struct OnboardingThumbnailImage_Previews: PreviewProvider {
static var previews: some View {
OnboardingThumbnailImage(imageName: "?????")
}
}
How can I accomplish this? The compiler requires me to specify a value inside OnboardingThumbnailImage_Previews so I have no clue. I have looked into Bindings but I don't need a 'two-way street' between the views, so I'm not sure.
Can I instead just perhaps leave Image() with no arguments inside, in order to inherit the default Image constructor? If I leave Image() I get an error: Cannot invoke initializer for type 'Image' with no arguments.
This is SwiftUI's way of asking you
What image do you want to show when this View is previewed?
You can only preview SwiftUI views on macOS Catalina, so if you are not using Catalina (like me), then this feature is not very relevant to you.
You are supposed to put the image that you want to see in the previews in the ???? bit. If you are not using Catalina, or you just don't want to preview it, you can just delete the whole OnboardingThumbnailImage_Previews struct.
Also note that you can't "subclass" another view in SwiftUI. All you can do is composition, which is what you have done here. SwiftUI's design favours composition over inheritance. You can find explanations of this concept in these pages: 1, 2.
In your struct view, the variable imageName needs value for initialization. as it should be string, because you define a string variable and use it in your Image. To ignore the error you can set an empty value to your variable to ignore the requirement to init in view construction
var imageName: String = ""

SwiftUI view sometimes creates Thread 1: EXC_BAD_ACCESS (code=1, address=0x6002005b8368), when I put array as a parameter

SwiftUI View file
struct NoteListView: View {
#EnvironmentObject var presenter: NoteListPresenter
var body: some View {
NavigationView{
AddNoteButton()
Text(presenter.noteViewModels[0].title)
}
}
}
struct NoteListView_Previews: PreviewProvider {
static var previews: some View {
NoteListView()
}
}
I first got this error when I finished writing the logic and started to writing Views. After add my custom button AddNoteButton() to main view, it gave the following error, although it worked before I added this button. I tried to rewrite my views, but although it works at the beginning at some random point of time it throws this error again(by other words sometimes it works, but when i add some irrelevant code it stops working and discarding changes doesn't solve the problem). It always highlights line, where I use noteViewModels array inside of the NoteListView.
Also I added method which prints array to presenter and it always prints everything.
func printAll(){
for element in self.noteViewModels{
print(element.title)
}
}
I can not add other files to question, because there is too many of them. But i hope that I gave enough information, If you think that there is not enough information you are free to ask me or you can check out github:
https://github.com/ShynggysSaparbek/ViperNotesWithRealm/
Xcode version 11.3
Mac OS version Catalina 10.15.2

SwiftUI - NavigationView Error message - Argument passed to call that takes no arguments

I am trying to implement a really basic NavigationView in SwiftUI. When I try the sample code that I have seen on other websites it generates an error message in Xcode. I am not sure why or how to fix this.
I have tried to clean the project, quit Xcode-Beta and restart it but that did not work.
struct ContentView : View {
var body: some View {
NavigationView {
Text("This is a great app")
}
}
}
I thought the code above should work but the error I get says:
"Argument passed to call that takes no arguments."
Any ideas or suggestions?
VStack can only take 10 argument.
If more, there will be error, so you should make it nested.
from
VStack{
}
to
VStack{
VStack{
}
VStack{
}
}
I had this same error message too and figured out what I did wrong and then kind of felt like an idiot. Ha ha.
Take a look:
It took me a while to figure out that my struct was the same name as a previously defined struct VStack. Whoops!
So I'm wondering if you had a file in your project that did this too.
check-in your app is there any Swifui class with the name NavigationView.
also when you jump to the definition from NavigationView it should refer to:
#available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 7.0, *)
public struct NavigationView<Content> : View where Content : View {
public init(#ViewBuilder content: () -> Content)
/// The type of view representing the body of this view.
///
/// When you create a custom view, Swift infers this type from your
/// implementation of the required `body` property.
public typealias Body = Never
}
Testing Xcode 11.2.1 and it's still buggy. I noticed when I keep adding primitive views to my ContentView, I start getting errors like
"Argument passed to call that takes no arguments",
"Type of expression is ambiguous without more context" etc. on primitive views which worked before.
When I replaced, for example,
ScrollView {
VStack {
Text
Button
Image
Text
Button
Image
Text
Button
Image
...
}
}
with
ScrollView {
VStack {
VStack {
Text
Button
Image
}
VStack {
Text
Button
Image
}
VStack {
Text
Button
Image
}
...
}
my code started to compile and run again.
I found this problem when I accidentally try to redefine Text struct. Check if you naming your custom class the same as those in SwiftUI.
#Matteo Pacini helped me find the answer. When I started a new Xcode Project just to test the code above everything worked. I had a lot of files and was testing a lot of different code while experimenting with SwiftUI in my other project and for some reason XCode was always generating this error.
When I tried everything in a new project it worked. Something to be aware of while testing. Hope this helps others avoid similar problems.
Embed the 'Text("This is a great app")' in a VStack
struct ContentView : View {
var body: some View {
NavigationView {
Stack {
Text("This is a great app")
}
}
}
}