diniska / modal-view

Present Modal view with Swift UI in the same way you would do with NavigationView
MIT License
92 stars 9 forks source link

Passing object and allowing dismiss? #7

Open ozumado opened 4 years ago

ozumado commented 4 years ago

Hello there,

I'm just learning SwiftUI and I faced a problem while using this library (which is awesome and simple btw.). Is it possible to pass an object to modal view and enable dismiss action?

ModalLink(destination: DetailedView(item:item).init(dismiss:))

Doesn't seem to work... I'm either able to only pass an object or enable dismiss action.

ModalLink(destination: DetailedView(item:item) ModalLink(destination: DetailedView.init(dismiss:))

Any clues?

diniska commented 4 years ago

Hello @ozumado. Sorry for the delay with answer, just saw your message. There is definitely no restriction on passing the object and dismiss closure at the same time. In fact, ModalLink accepts a closure that is supposed to return a View. So, instead of passing a short version of init closure for the DetailView, we can use a full version like this:

ModalLink(destination: { dismiss in DetailedView(item: "Item", dismiss: dismiss)}) {
    Text("Present")
}

Or you can rewrite the same in a next way depending on the syntax preferences:

ModalLink(
    destination: { DetailedView(item: "Item", dismiss: $0) },
    label: { Text("Present") }
)

Please, let me know if you have some other questions or improvements suggestions about the library.

ozumado commented 4 years ago

Thanks for your reply, I decided to use native way to close a View instead (swift @Environment(\.presentationMode) var presentationMode and swift self.presentationMode.wrappedValue.dismiss()) and it works fine now except for one thing: when presenting a ModalView with child ModalLinks once you scroll that ModalView it "clicks" the links and open that child ModalView. This also occurs when using native .sheet(), so it must be some Apple Bug. Currently I have no idea how to prevent it from opening links upon scroll...

ozumado commented 4 years ago

Ok, so I overcome this issue by using .onTapGesture() instead of Button() while using native .sheet(). It looks like Button is the issue here.

I'm not an expert, but maybe this change could fix the issue in the library: Change this:

    public var body: some View {
        Button(action: presentModalView){ label }
    }

To this:

    public var body: some View {
        label.onTapGesture() { self.presentModalView() }
    }

But now the "fake button" doesn't have the same feel as real one - not changing opacity while pressed down, so I currently overcome this issue by creating a Button that does nothing, and applying .onTapGesture() that trigger the action:

    public var body: some View {
        Button(action: { }) { label.onTapGesture() { self.presentModalView() } }
    }