NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

pass data back from sheet

Forums > SwiftUI

In View1 I invoke View2 as a sheet. In View2 I present a list of core data rows and a user selects one. How do I get the information about the selected item back to View1? Or, is there another way to do what I want.

I have Entity1 that has a one to many relationship to Entity2. In View1 the user is looking at an Entity1 and hits the button to indicate she wants to add an Entity2 to the relationship. View2 appears, as a sheet, he picks one of the rows and does whatever. Now I am back in the onDismiss for the sheet in View1 and I want to add what he selected in View2 to the relationship in ENtity1. My idea is that I would pass something back from View2. How do I do that, or is there another way?

Said another way. I have an Entity1 and I want to add an Entity2, that I select from the existing Entity2s, to the relationship.

I just want to know how to do it. I don't need code. It will be better practice for me if I write it. I could put stuff in some other class , known to both views, to pass data but that doesn't seem like something I should do in SwiftUI. It is prone to all sorts of errors both creating it and especially later when updating it. Lots of comments in the code to explain what is going on.

   

I almost got it. Entity2 is an observableObject, so I can stick

  @ObservedObject var entity2 = Entity2()

in View1. Then in View2 I can put

  @ObservedObject var xentity2: Entity2

In View2 I pick the Entity2 I want to use and... You can't do

              xentity2 = entity2

But, I could just write a copy function for Entity2 and just do xentity2.copy(xentity2). Great, but Entity2 is a class generated by CoreData and I have no idea what stuff CoreData may have put in the class since all I have is an extension to the class, to say nothing of they may cnage it in the future.

The work around I see is create a class of my own that contains what is required to find a Entity2 in CoreData. Use that to pass data between View1 and View2. In View2 I get the Entity2, from CoreData, copy the parts that make it unique to my class. Back in View1 I get the stuff that makes the Entity2 unique and use that as a filter so CoreData can get the same Entity2 that View2 already had. Now I can associate the Entity2 I just got with my Entity1. This seems like more work and a lot of places where bugs can creep in.

   

Instead of passing data back to View1, you can do all this in View2 because it inherits the environment, including the managed object context.

In View2, insert the selected object from Entity2 in the related attribute (property) of Entity1.

   

p.s. I think it would be helpful to include "Core Data" in the title of all posts that relate to core data because it is a subject in which only a few participants here seem to have expertise.

(Disclaimer: I am a neophyte myself, so take my suggestions with a large dose of salt.)

   

Ok. I found it. I did not realise you could pass functions as parameters to views. Here is an example. Player is a class to pass back and forth. The main view sets a variable and PlayerEditView is displayed as a sheet. The cancel button changes the Player class and then invokes the passed function. The passed function, back in the original view, has the updated player and can save it away ther. I know sheet can invoke a function when the sheet is done but that function has no access to the data in the sheet. My passed function also runs in the first view but it is invoked in the second and can have any parameters you want.

class Player {
  var name = "Peter"
}
struct PlayerEditView: View {
  var player: Player = Player()
  var functio: (_ play: Player) -> Void
  @Environment(\.dismiss) var dismiss

  var body: some View {
    Button ("cancel") {
      player.name  = "xx"
      functio(player)
      dismiss()
    }
  }
}

struct ContentView: View {
  @State private var showingDetail = false
  private var player = Player()

  var body: some View {
    VStack {
      Text("Hello, world!")
        .padding()
        .onTapGesture {
          showingDetail.toggle()
        }
    }
    .sheet(isPresented: $showingDetail) {
      PlayerEditView(player: player, functio: it)
    }
  }
  func it(play: Player) {
    print (play.name)
    print ("back")
  }
}

   

Hacking with Swift is sponsored by Play

SPONSORED Play is the first native iOS design tool created for designers and engineers. You can install Play for iOS and iPad today and sign up to check out the Beta of our macOS app with SwiftUI code export. We're also hiring engineers!

Click to learn more about Play!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.