How to assign an optional Binding parameter in SwiftUI?

北城余情 提交于 2020-06-23 05:50:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!