Laura Ramírez
Laura Ramírez

Reputation: 107

ImagePicker in array

I am trying to make a dynamic image selection with the help of an array, but the problem I have is that I select the first position and the photo loads in the first position, but if I select another position, the image always loads in the first position.

I am occupying a single .sheet within the foreach, it is worth mentioning that what I want to achieve is a number of images, not a fixed size

code:

import SwiftUI


struct Research {
    var id: Int
    var name: String
    var date: String
    var aux: Int
    var imagen1: UIImage
    var imagen2: UIImage
    var imagen3: UIImage
    var imagen4: UIImage
    var imagen5: UIImage
    var imagen6: UIImage
    
}

struct ContentView: View {
    @State var dataResearch : [Research] = []
    @State var aux: Int = 0
    @State var showPicker: Bool = false //  I imagine that this variable must be unique per element
    @State var sourceType: UIImagePickerController.SourceType = .photoLibrary
    
    var body: some View {
        VStack{
            ForEach($dataResearch, id: \.aux) { $i in
                VStack{
                    Image(uiImage:  i.imagen1)
                      .resizable()
                      .scaledToFill()
                      .frame(width: 200, height: 200)
                      .edgesIgnoringSafeArea(.all)
                      .onTapGesture(){
                          showPicker = true
                      }
                    Image(uiImage:  i.imagen2)
                      .resizable()
                      .scaledToFill()
                      .frame(width: 200, height: 200)
                      .edgesIgnoringSafeArea(.all)
                      .onTapGesture(){
                          showPicker = true
                      }
                      
                }
                .sheet(isPresented: $showPicker) {
                    ImagePicker(sourceType: sourceType, selectedImage: $i.imagen1)
                        .ignoresSafeArea()
                }
            }
        }
        .onAppear(){
            getRequest()
        }
    }
    
    
    func getRequest(){
        let image1: UIImage =  UIImage(named: "default_image")!
        let image2: UIImage  =  UIImage(named: "default_image")!
        let image3: UIImage  =  UIImage(named: "default_image")!
        let image4: UIImage  =  UIImage(named: "default_image")!
        let image5: UIImage  =  UIImage(named: "default_image")!
        let image6: UIImage  =  UIImage(named: "default_image")!
       
        let row = Research(id: 0, name: "", date: "", aux: aux, imagen1: image1, imagen2: image2, imagen3: image3, imagen4: image4, imagen5: image5, imagen6: image6)
         dataResearch.append(row)
        
        aux = aux + 1
    }
    
}

IMAGE PICKER

import UIKit
import SwiftUI

struct ImagePicker: UIViewControllerRepresentable {
    
    var sourceType: UIImagePickerController.SourceType = .photoLibrary
    
    @Binding var selectedImage: UIImage
    
    //@Binding var selectedImage: SelectImage
    
    @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
            print("aqui vemos-- ", parent)
            print("aqui vemos-- ", parent.selectedImage)
        }
        
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            
            if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
                parent.selectedImage = image
                //var row1 = SelectImage(id: 0, uiImage: image ,name:"")
                //parent.selectedImage.uiImage = image
            }
            
            parent.presentationMode.wrappedValue.dismiss()
        }
    }
}


enter image description here

Upvotes: 0

Views: 394

Answers (1)

jnpdx
jnpdx

Reputation: 52377

This was a little bit complicated because of the structure of Research and the fact that it has so many image fields (that aren't in an array). I'd suggest that it's possible that your model could use a refactor, but since I don't have any information about what the end goal is, I don't know exactly what that would involve yet.

With your current code, you can set a selected item and then set an additional variable that determines which imagen(X) property it should be bound to:

struct ContentView: View {
    @State private var dataResearch : [Research] = []
    @State private var aux: Int = 0
    @State private var pickerItem : Binding<Research>? // the item from ForEach
    
    private enum SelectedImage {
        case imagen1, imagen2
    }
    
    @State private var selectedImage : SelectedImage? //which image gets selected 
    
    var body: some View {
        VStack{
            ForEach($dataResearch, id: \.aux) { $i in
                VStack{
                    Image(uiImage:  i.imagen1)
                        .resizable()
                        .scaledToFill()
                        .frame(width: 200, height: 200)
                        .edgesIgnoringSafeArea(.all)
                        .onTapGesture(){
                            pickerItem = $i
                            selectedImage = .imagen1
                        }
                    Image(uiImage:  i.imagen2)
                        .resizable()
                        .scaledToFill()
                        .frame(width: 200, height: 200)
                        .edgesIgnoringSafeArea(.all)
                        .onTapGesture(){
                            pickerItem = $i
                            selectedImage = .imagen2
                        }
                }
            }
            .sheet(item: $pickerItem) { [selectedImage] item in
                VStack {
                    if let selectedImage = selectedImage {
                        switch selectedImage {
                        case .imagen1:
                            ImagePicker(selectedImage: item.imagen1)
                        case .imagen2:
                            ImagePicker(selectedImage: item.imagen2)
                        }
                    }
                }
                .ignoresSafeArea()
            }
        }
        .onAppear(){
            getRequest()
        }
    }
    
    
    func getRequest(){
        let image1: UIImage =  UIImage(systemName: "pencil")!
        let image2: UIImage  =   UIImage(systemName: "pencil")!
        let image3: UIImage  =   UIImage(systemName: "pencil")!
        let image4: UIImage  =   UIImage(systemName: "pencil")!
        let image5: UIImage  =   UIImage(systemName: "pencil")!
        let image6: UIImage  =   UIImage(systemName: "pencil")!
        
        let row = Research(id: 0, name: "", date: "", aux: aux, imagen1: image1, imagen2: image2, imagen3: image3, imagen4: image4, imagen5: image5, imagen6: image6)
        dataResearch.append(row)
        
        aux = aux + 1
    }
}

Upvotes: 1

Related Questions