stleamist / BetterSafariView

A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI.
MIT License
586 stars 56 forks source link

Expose item to onDismiss closure #6

Closed mlinzner closed 3 years ago

mlinzner commented 4 years ago

Awesome work with v2, congrats :)

It would be useful if the presented item is also exposed to the onDismiss closure, to adjust "cleanup" actions based on the item that was visible. Think of tracking each item that was opened, …

struct CustomItem {
 var id: String
  var name: String
  var url: URL?
  //…
}

struct ArticleList : View {
  // …
  @State private var itemToShow: CustomItem? = nil

  var body: some View {
      List {
        ForEach(viewModel.feedItems) { item in
           Button(action: { itemToShow = item }) {
               // …
          }
        }
      }.safariView(item: $itemToShow, onDismiss: { item in // <-- not possible at the moment
        print("Mark Item \(item.name) as read")
      }) { item in
            SafariView(
              url: item.url,
               configuration: SafariView.Configuration(
                // …
                ))
        }
  }
stleamist commented 3 years ago

Thank you for your good suggestion :)

Though it would be hard to expose item since this modifier aims to follow API design of sheet(item:onDismiss:content:), I think what you want can be achieved using onChange(of:perform:) modifier.

struct CustomItem {
    var id: String
    var name: String
    var url: URL?
    // …
}

struct ArticleList : View {
    // …
    @State private var itemToShow: CustomItem? = nil
    @State private var shownItem: CustomItem? = nil

    var body: some View {
        List {
            ForEach(viewModel.feedItems) { item in
                Button(action: { itemToShow = item }) {
                    // …
                }
            }
        }
        .onChange(of: itemToShow) {
            shownItem = itemToShow
        }
        .safariView(
            item: $itemToShow,
            onDismiss: {
                print("Mark Item \(shownItem.name) as read")
                shownItem = nil
            }
        ) { item in
            SafariView(
                url: item.url,
                configuration: SafariView.Configuration(
                    // …
                )
            )
        }
    }
}