Home > Software design >  Value conversion error when trying to make a swift toggle button
Value conversion error when trying to make a swift toggle button

Time:12-03

At the moment I'm hacking away at swift to learn the language and I'm coming at it from a java/C perspective. I'm trying to make an app for a game I play called World War II Online. However I can't get my head around why I'm getting a binding error when trying to code in the toggle for remembering a password. Below is my code for the landing page for my app.

struct ContentView: View {
  @State private var empty_field = ""
  @State private var passwordState = false
  let userfieldTitle : String = "username"
  let passwordFieldTitle : String = "password"
  let landingPageTitle = "World War II Online"
  let toggleName = "remember password"

var body: some View
{
    Text(landingPageTitle).font(.largeTitle)
    Section {
        Form{
            VStack
            {
                
                TextField(userfieldTitle,text : $empty_field)
                TextField(passwordFieldTitle,text : $empty_field)
                Toggle(toggleName, isOn: $passwordState){
                     print("hello world")   
                }
            }
            .padding()
        }
    }
}

I'm getting the error:

Cannot convert value of type 'Binding' to expected argument type 'KeyPath<(() -> ()).Element, Binding>'

I'm really bad in understanding bindings and properties. Is there something I've been code blind to ?

CodePudding user response:

You can't just put code in curly braces and have it execute without this extension.

public extension View {
  /// Execute imperative code.
  func callAsFunction(_ execute: () -> Void) -> Self {
    execute()
    return self
  }
}

CodePudding user response:

You have to probably stop thinking of SwiftUI like Java or C . It's not following the common OO paradigm for GUIs that Swing, MFC, Wx, etc use. It's something completely different.

A body in a View is returning data. Think of it more like JSON/XML that describes the view. There are some things in there that are like imperative code, but it's subtly different.

So, you can't just throw print statements in there whenever you want. You can inside of closures that are imperative actions (like a button click).

So, just remove the block you put in after the Toggle. If you are trying to print out something when the toggle changes, you can look at the $passwordState variable you made.

For example:

Form {
    VStack {
        TextField(userfieldTitle,text : $empty_field)
        TextField(passwordFieldTitle,text : $empty_field)                         
        Toggle(toggleName, isOn: $passwordState)
        if passwordState {
            Text("hello world")
        }
    }
    .padding()
}

Don't think of that if as being like code that runs an if statement -- think of it more like an <IF> XML tag. That if is not run when the body function runs -- it's returned to the caller that reads the data-structure and figures out what to actually show by analyzing it and the currently shown view and applying diffs to change it from what it is to what it should be.

  • Related