问题
I'm trying to build a custom NavBar
with some optional Views
, like a searchbar (but only if the view needs to display it).
I need to pass some @State
properties with @Binding
down the views, basically. But I also need them to be Optional
parameters.
Here's an example:
struct NavBar: View {
var isSearchable: Bool?;
@Binding var searchTxt: String;
@Binding var searchIsOn: Bool;
var navBarTitle: String;
var navBarAction: (() -> Void)?;
var navBarImage: String?;
init(navBarTitle: String, navBarAction: (() -> Void)? = nil, navBarImage: String? = nil, isSearchable: Bool? = false, searchTxt: (Binding<String>)?, searchIsOn : (Binding<Bool>)?) {
self.navBarTitle = navBarTitle;
if(navBarAction != nil) {
self.navBarAction = navBarAction!;
}
if(navBarImage != nil) {
self.navBarImage = navBarImage!;
}
self.isSearchable = isSearchable;
self._searchTxt = (searchTxt != nil) ? (searchTxt!).binding : nil;
self._searchIsOn = (searchIsOn != nil) ? (searchIsOn!).binding : nil;
assert((navBarAction != nil) ? navBarImage != nil : true);
assert((isSearchable! == true) ? (searchTxt!.value.count > 0) : true);
}
// var body ....
}
The properties I'm talking about are searchIsOn
and searchTxt
.
But doing the assignment self._searchTxt = searchTxt
or self._searchIsOn = searchIsOn
throws a compile error:
Cannot assign value of type 'Binding?' to type 'Binding'
Do you know how could I resolve this issue?
Or is there a better way to do what I'm trying to do?
回答1:
@Binding var searchTxt: String?
init(searchTxt: Binding<String?>?) {
self._searchTxt = searchTxt ?? Binding.constant(nil)
}
回答2:
What you want is an Optional Binding of a String, not a Binding of an Optional String. I don't think you can achieve that by using the @Binding annotation.
However, you don't need to used the annotation. You can just declare the variable as a Binding:
Your
@Binding var searchTxt: String?;
then turns to this
var searchTxt: Binding<String?>
But this way the syntax lets you place the ? wherever you want. So if you move it to the end, after the Binding's closing tag, you have what you want.
var searchTxt: Binding<String>?
If you want to access the String inside your Binding, you have to use the wrappedValue property.
Text(searchTxt!.wrappedValue)
回答3:
I have a UIViewControllerRepresentable
in order to use UIImagePickerController
. If you've ever used this image picker, you know that you need to image returned to be an optional. So in my ContentView
I declared:
@State var uiImage: UIImage?
...
if uiImage != nil {
Image(uiImage: $uiImage
} else {
Rectangle()
}
And in my ImagePicker
(that's my SwiftUI
view) I have:
@Binding var uiImage: UIImage?
Works like a charm.
(The if
statement is pretty much psuedo-code, as I'm actually using an MTKView
and a CIImage
, but your get the drift - you use the optional just as you would anywhere else.)
来源:https://stackoverflow.com/questions/57163055/how-to-assign-an-optional-binding-parameter-in-swiftui