1

I have the following code:

@State var message: String = ""

var body: some View {
        VStack {
            ZStack(alignment: .topLeading) {
                TextEditor(text: Binding($message))
                    .frame(minHeight: 30, alignment: .leading)
                    .cornerRadius(6.0)
                    .multilineTextAlignment(.leading)
                Text(message ?? "Message")
                    .padding(.leading, 4)
                    .opacity(message == "" ? 1 : 0)
                }
                .font(.body)
        }
    }
}

When I try to execute the code, it says "Cannot convert value of type 'Binding<String?>' to expected argument type 'Binding<String>'" next to TextEditor(text: Binding($message) Why am I getting this error?

1
  • 2
    Remove the Binding(). Just use TextEditor(text: $message) Commented Nov 14, 2020 at 0:50

2 Answers 2

2

The error is originated from this line

Text(message ?? "Message")

because compiler tries to infer type and this line shows that type should be optional, but editor expects not optional, so you got conflict and error. Your message state is not optional so you just need to move default value directly in intializer.

Here is corrected variant:

struct DemoView: View {
    @State var message: String = "Message"
    
    var body: some View {
        VStack {
            ZStack(alignment: .topLeading) {
                TextEditor(text: $message)
                    .frame(minHeight: 30, alignment: .leading)
                    .cornerRadius(6.0)
                    .multilineTextAlignment(.leading)
                Text(message)
                    .padding(.leading, 4)
                    .opacity(message == "" ? 1 : 0)
            }
            .font(.body)
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

I got an error similar to this because I forgot to do string interpolation on an Int. It was confusing but once I displayed it correctly it worked.

List(myListOfIntegers) { intItem in
  Text("\(intItem)") // RIGHT
  Text(intItem) // WRONG: Gives 2 errors:
  // Error 1 on the List(myListOfIntegers) code: Cannot convert value 'myListOfIntegers' of type '[Int]' to expected type 'Binding<[Int]>', use wrapper instead
  // Error 2 on the Text(intItem) code: Initializer 'init(_:)' requires that 'Binding<Int>' conform to 'StringProtocol'
}

As Asperi mentioned, the compiler is trying to infer the type, and in my case the Int fooled the compiler into thinking it needed a binding value.

2 Comments

This has nothing to do with optional values nor bindings so it’s not a relevant answer to the question just because the error message is similar.
While true this does not directly answer the question, my answer discusses the same compiler inference confusion that the question answer describes. Considering this is the first link I came upon when I searched the Error 2, I thought it could be worthwhile to add this answer with my experience.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.