TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

SOLVED: Binding Variable Won't Preview

Forums > SwiftUI

Xcode 13.1 SwiftUI App Name "Builder"

File List:

Folder "Builder"

  • BuilderApp.swift
  • ContentView.swift
  • FormView.swift
  • Assets

Folder "Preview Content"

  • Preview Assets

FUNCTION I am making a form that user interacts with TextField, Toggle, and other elements.

PROBLEM My FormView.swift file won't preview when I set the variables to bindings. I get a "missing arguments for parameters" error when I try to preview on canvas.

File 'ContentView.swift'

import SwiftUI

struct ContentView: View {

    @State private var variableOne = false

File 'FormView.swift'

import Foundation
import SwiftUI

struct FormView: View {
    @Binding var variableOne: Bool

FormView.swift A form view is used to allow user to interact with a toggle that sets 'variableOne'. This was working in preview when the variable was local.

File 'FormView.swift' The following struct reports the error "missing arguments for parameters".

struct FormView_Previews: PreviewProvider {

    static var previews: some View {
        FormView()
    }
}

I tried:

struct FormView_Previews: PreviewProvider {

    static var previews: some View {
        FormView(dangerToSelf: .constant(true), dangerToOthers: .constant(true), gravelyDisabled: .constant(true))
    }
}

I also tried:

struct FormView_Previews: PreviewProvider {

    static var previews: some View {
        FormView(variableOne: $variableOne)
    }
}

I tried a bunch of others things and I've read as much on the issue as I can. I can't seem to fix this. It seems related to the variables being changed to bindings. I want to call different forms in different swift files from within ContentView.

Thanks for guidance and help.

3      

@ik_  

struct ContentView: View {

    @State private var variableOne = false

    var body: some View {

    FormView(variableOne: $variableOne)

    }
}

struct FormView: View {
    @Binding var variableOne: Bool

    var body: some View {
        Text("Test")
    }
}

Is this what you are trying to achieve? I assume you want to call FormView in ContentView?

3      

Thanks for replying!

I do intend to call it from contentview and I have no issue with the bindings, etc. What I want is to be able to preview formview while I create it.

Because the app has many sections I wanted to call them in contentview so it doesn't have all the code in one file.

The formview preview code is what is giving me problems.

3      

This should work.

struct FormView_Previews: PreviewProvider {
  static var previews: some View {
    FormView(variableOne: .constant(true))
  }
}

8      

@hatsushira provides the correct answer. But I sense from your examples you're confused about the PreviewProvider. (@idriskhenchil provides the correct answer for a compiled application.)

When developing SwiftUI apps, it's a great practice to isolate functionality into small pieces. You did this with your FormView. However in a full SwiftUI application, all the pieces work together and they share information. Data bits can be passed from one SwiftUI component to others.

But when you invoke a PreviewProvider, you're telling XCode to isolate this one component and show you what it looks like while you're developing it. In this case, it doesn't get data from other parts of your application. In Preview mode, it's all on its own.

Think of a car engine. The carburetor mixes fuel from petrol tanks with air flowing in from the air filters. The air-to-fuel ratio mix is governed by input from the accelerator mechanism. These inputs are from different parts of the car's engine.

But what if you pulled the carburetor OUT of the engine. How would you test it? You'd have to simulate the accelerator mechanism, perhaps with your finger. You'd have to give it air from a fake air source. You simulate operational input from fake sources.

THIS is what you have to do with PreviewProviders. You have to give your FormView fake input so you can see what it does, and how it reacts.

XCode gave you an exact message, "missing arguments for parameters". Maybe now you see what this means. When you pulled your FormView out into a PreviewProvider, you need to give it fake data. In this case, the FormView needs you to provide a boolean for ValueOne! FormOne says it NEEDS a boolean (sent in as a binding) to create itself.

In your examples, you first tried creating FormView with dangerToSelf: and dangerToOthers: (FAIL) Next you tried to create a FormView by wiring it up to $variableOne (which doesn't exist in the Preview) from a working application (also FAIL).

These attempts failed because you pulled the FormView out of its normal operating environment. @hatsushira solved the problem by creating a FormView using fake binding data. In his example, he fakes a binding<bool> by using the .constant(true) or .constant(false) construction.

Hope this clarifies PreviewProvider for you? When you watch Paul's (and others') videos and you see PreviewProviders, always think to yourself, "What's their magic potion for providing fake data to the Preview?" You'll quickly appreciate some of their shortcuts!

By the way, yours is an excellent example for others who seek help! Providing your issue, along with your attempted solutions it a GREAT way to isolate the knowledge gap. Well done.

9      

Related observation:

This week I was watching @twostraw's recent tutorials for Day 58 of 100 Days of SwiftUI.

Day 58 CoreData Dynamic Filtering

@5:50 Paul creates a Struct and adds a var parameter named "fetchRequest". XCode immediately complains that he did not provide a value for this new var for the Preview. He gets the same message that you did, "Missing argument for parameter...."

I got out my 100 Days of SwiftUI notebook and was ready to write down the secret sauce. Namely I wondered how he was going to provide a fake management object context and a fake fetchRequest to his PreviewProvider. These are not trivial types. These are heavy duty CoreData behemoths.

@twostraws continues the lecture for another four minutes before addressing the Preview error.

In the end he simply says, "the preview is not required here, so it's safe to ZAP it."

DENIED! Ouch! I was hoping he'd reveal the secret. But in the end, it might have been a bit too much for this already long-ish tutorial.

4      

The dangerToSelf and dangerToOthers references were original from my code and I forgot to adapt it to a more understandable name, my bad.

Hatsushira, thanks for the solution, I read/saw some things on this and it didnt work for me but I'm going to try yours out and trust what others have said about your solution.

Obelix, I gave you the solution because you really made it easier to understand. I was seeking a solution but you helped me understand the problem in a deeper way.

Hope this post helps others.

Thanks to everyone who took time to read and reply!

6      

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.