Search code examples
xcodegoogle-cloud-firestoreswiftuiuiimagepickercontroller

SwiftUI / imagepicker / firebasefirestore - image uploads properly but does not show on the imageview


I'm working on this project where a user can go on a setting view and pick an image (using imagepicker) as a profile image. The image is then uploaded on Firebasefirestore, and should be displayed in a circle on the same screen. The image picker works and the selected image gets uploaded properly on firebasefirestore, however the selected image does not appear properly in the circle. Can you help me out?

Here's the relevant part of my code. Happy to share the code of the imagepicker if necessary.

import SwiftUI

struct SettingsView: View {
  @ObservedObject var settingsViewModel = SettingsViewModel()
  @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
  @State private var presented = false
  @State private var isShowPhotoLibrary = false
  @State private var image = UIImage()

var body: some View {
    NavigationView {
      VStack {
        
        Image(uiImage:self.image) // <-- here is where I want the image to appear
            .resizable()
            .aspectRatio(contentMode: .fill)
            .frame(width: 250.0, height: 250.0, alignment: .center)
            .clipShape(/*@START_MENU_TOKEN@*/Circle()/*@END_MENU_TOKEN@*/)
            .overlay(Circle().stroke(Color.white, lineWidth: 4))
            .shadow(radius: 10)
            .scaledToFit()

        Text("Project")
          .font(.title)
          .fontWeight(.semibold)
        
        Form {
          Section {
            HStack {
              Image(systemName: "checkmark.circle")
              Text("Upload profile image")
              Spacer()
              Text("Plain")
                .onTapGesture {
                    self.isShowPhotoLibrary = true
                }
                .sheet(isPresented: $isShowPhotoLibrary) {
                    ImagePicker(sourceType: .photoLibrary, selectedImage: self.$image)
                }
                
            }
          }
          
          AccountSection(settingsViewModel: self.settingsViewModel)
        }
        
        .navigationBarTitle("Settings", displayMode: .inline)
        .navigationBarItems(trailing:
          Button(action: { self.presentationMode.wrappedValue.dismiss() }) {
            Text("Done")
        })
        
      }
        
    }
 
  }
    
}

image picker:

import UIKit
import SwiftUI

struct ImagePicker: UIViewControllerRepresentable {
    
    var sourceType: UIImagePickerController.SourceType = .photoLibrary
    
    @Binding var selectedImage: UIImage
    @Environment(\.presentationMode) private var presentationMode

    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        
        let imagePicker = UIImagePickerController()
        imagePicker.allowsEditing = false
        imagePicker.sourceType = sourceType
        imagePicker.delegate = context.coordinator
        
        return imagePicker
    }
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
        
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        
        var parent: ImagePicker
        
        init(_ parent: ImagePicker) {
            self.parent = parent
        }
        
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            
            if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
                
                uploadprofileImage(image: image)
                
            }
            
            parent.presentationMode.wrappedValue.dismiss()
        }
    }
}

Solution

  • You never set @Binding var selectedImage, so the Image back in the SettingsView doesn't update.

    if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
        parent.selectedImage = image /// add this line!
        uploadprofileImage(image: image)        
    }