How do you pass SwiftUI Bindings to other objects in iOS 13 Beta 4?

In Xcode 11 Beta 4, I'm no longer able to pass `Binding`s down a view hierarchy. For example, imagine I have a list view called `CoolListView`, which renders multiple `CoolListRow` subviews, and the user is able to change a value from the list superview level that I'd like to percolate down to and update the row subviews:


public struct CoolListRow : View {
    @Binding var currentStep: Int

    public var body: some View {
       // ...
    }

    public init(currentStep: Binding<Int>) {
        self.$currentStep = currentStep
    }
}


In Beta 3 and earlier, I would be able to pass this `Binding` as an argument to my subviews, but now in Beta 4, Xcode complains `Cannot assign to property: '$currentStep' is immutable`. Any ideas on how to resolve this?

Accepted Reply

For those in the same situation, I've just figured out the answer – replace the property wrapper prefix with a type update in your variable declaration:


public struct CoolListRow : View {
    var currentStep: Binding<Int>

    public var body: some View {
        // ...
    }

    public init(currentStep: Binding<Int>) {
        self.currentStep = currentStep
    }
}

Replies

For those in the same situation, I've just figured out the answer – replace the property wrapper prefix with a type update in your variable declaration:


public struct CoolListRow : View {
    var currentStep: Binding<Int>

    public var body: some View {
        // ...
    }

    public init(currentStep: Binding<Int>) {
        self.currentStep = currentStep
    }
}

I thought it was just me (and probably spent way too much time deciding if it was or not), but I'm wondering if you're still having issues. Your solution allows your problem to compile, but I don't believe it's correct?


When using @Binding it's possible to use the variable as if it were a regular variable, such as:

@Binding var isPlaying: Bool

isPlaying.toggle()


But if we change the type as suggested, we have to use the variable by first going through value:

var isPlaying: Binding<Bool>

isPlaying.value.toggle()


Are you having any additionally issues like I mentioned after making the changes that you've suggested?

After spending way too much time on this issue, I happend upon a stackoverflow post on twitter that showed the new syntax for beta 4.

https://stackoverflow.com/questions/56973959/swiftui-how-to-implement-a-custom-init-with-binding-variables


When initializing a binding variable, the syntax has changed from a $ to an underscore.


Using the example you gave in the original post, here's the corrected code for beta 4:


public struct CoolListRow : View {  
    @Binding var currentStep: Int  
  
    public var body: some View {  
       // ...  
    }  
  
    public init(currentStep: Binding<Int>) {  
        self._currentStep = currentStep  
    }  
} 


Hope this helps.

Thanks @sammyjojo, this saved my life! This sould be the accepted answer.

This is how I did it...

Code Block
class iAPManager: NSObject, SKPaymentTransactionObserver {
   
  var isPro: Binding<Bool>
  let productID = "xyz"
   
  public init(isPro: Binding<Bool>) {
    self.isPro = isPro
  }
-- your code here --
}


To change the binding value:
Code Block
self.isPro.wrappedValue = true
(or)
self.isPro.wrappedValue.toggle()