Search code examples
iosswiftswiftuiuiviewrepresentableswift-structs

Do something as soon as UIViewRepresentable is instantiated


This seems like a straightforward question, but I have not been able to find any solutions in the Swift docs. When I was programming in Kotlin, it was common to use the init() method of a class to perform some work in order to get the class set up and ready for use.

Now I am creating a UIViewRepresentable and would like to do something as soon as this struct is initialized. It seems that the init() method for structs is only concerned with member initialization.

For example, the .onAppear method for a View provides this functionality as follows:

struct MapView: View {
    @StateObject private var viewModel = MapViewModel()
    
    var body: some View {
        Map(coordinateRegion: $viewModel.region,
            interactionModes: .all,
            showsUserLocation: true)
        .onAppear { 
            // this will occur as soon as the View appears
            viewModel.safeCreateLocationManager()
            
        }
    }
}

But now when defining a UIViewRepresentable struct I am wishing to do the same:

struct OverlayMapView: UIViewRepresentable {
    @StateObject private var viewModel = MapViewModel()
    
    // immediately do the following: 
    viewModel.safeCreateLocationManager()

    
    func makeUIView(context: Context) -> MKMapView {
        ...
    }
    
    func updateUIView(_ uiView: MKMapView, context: UIViewRepresentableContext<OverlayMapView>) {
        ...
    }
}

Solution

  • It is possible but would be not correct (so I will not tell even how), instead use it

    struct OverlayMapView: UIViewRepresentable {
        @StateObject private var viewModel = MapViewModel()
        
        func makeUIView(context: Context) -> MKMapView {
           viewModel.safeCreateLocationManager()    // << here !!
    
           // view creation is next ...
    

    *the makeUIView is called after init and before onAppear