Joby Ingram-Dodd
Joby Ingram-Dodd

Reputation: 730

How do I show a SwiftUI overlay programmatically?

I have a form the User completes which includes an image upload, as this takes a little time to upload to the server I want to show a progress view of the upload.

I have created the view and connected it to the upload progress data which all works fine, and I can have it as a permanent overlay, but I would like to overlay it only when the upload button is pressed.

How do I do that?

my progress view


    struct ProgressIndicator: View {
        @State  var imageUploadAmount = 0.0
        var progress: Progress
        var body: some View {
            VStack {
                ProgressView("Uploading…", value: imageUploadAmount, total: 1)
            }.onReceive(progress.$upload, perform: { _ in
                imageUploadAmount = progress.upload
            })
        }
    }
    

the form view

struct AddAClimb: View {
    @EnvironmentObject var screenCoordinator: ScreenCoordinator
    @ObservedObject var progress = Progress()
    @State private var showingImagePicker = false
    @State private var selectedTypeIndex: Int = 0
    @State private var name = ""
    @State private var grade = ""
    @State private var description = ""
    @State private var country = ""
    @State private var region = ""
    @State private var crag = ""
    @State private var section = ""
    @State private var height = ""
    @State private var long = "0.0"
    @State private var lat = "0.0"
    @State private var stars = 0
    @State private var image: Image? //= "default"
    @State private var imageUrl = "default"
    @State private var inputImage: UIImage?
    @State private var icons = [""]
    @State  var pitchCount = 1
    @State private var pitch = ["",""]
    let cloudinary = CLDCloudinary(configuration: ImageController().config)
    private var climbTypeOptions = ["Trad", "Sport", "Boulder", "Solo", "Aid"]
    var body: some View {
        Form{
            Section(header: Text("Climb Detial")) {
                HStack{
                    TextField("Climb Name", text: $name)
                }
                Picker("Climb Type", selection: $selectedTypeIndex){
                    ForEach(0..<climbTypeOptions.count){
                        Text(self.climbTypeOptions[$0])
                    }
                }.pickerStyle(SegmentedPickerStyle())
                HStack{
                    Text("Grade:")
                    TextField("enter the grade", text: $grade)
                }
                HStack{
                    Text("Height:")
                    TextField("enter the height", text: $height)
                }
                Text("Description:")
                TextEditor(text: $description)
                HStack{
                    Text("Pitches:")
                    Spacer()
                    Stepper(value: $pitchCount,
                            in: 1...100,
                            label: {
                                Text(" \(self.pitchCount)")
                            })
                }
                ForEach(0..<pitchCount){ x in
                    HStack{
                        Text("\(x + 1):")
                        TextField("Pitch Description", text: $pitch[x] )
                    }
                }
            }
            Section(header: Text("Location")) {
                
                TextField("Country", text: $country )
                TextField("Region", text: $region )
                TextField("Crag", text: $crag)
                TextField("Sector", text: $section)
                HStack{
                    Text("Longitude:")
                    TextField("Longitude", text: $long).keyboardType(.numbersAndPunctuation)
                }
                HStack{
                    Text("Latitude:")
                    TextField("Latitude", text: $lat).keyboardType(.numbersAndPunctuation)
                }
            }
            Section(header: Text("Images/Videos")) {
                image?.resizable().aspectRatio(contentMode: .fit)
                HStack{
                    Spacer()
                    Button(action: {
                        self.showingImagePicker = true
                    }, label: {
                        Text("Select an Image")
                    })
                    Spacer()
                }
                
            }
            Section(header: Text("Save")) {
                HStack{
                    Spacer()
                    Button(action:{
                        ClimbController().addNewClimbToDB(name: name, desc: description, country: country, region: region, crag: crag, sector: section, long: Double(long) ?? 0.0, lat: Double(lat) ?? 0.0, pitches: pitch, stars: stars, grade: grade, climbType: climbTypeOptions[selectedTypeIndex], icons: icons, imageUrl: imageUrl, height: Double(height) ?? 1, inputImage: inputImage, progress: progress, screenCoordinator: screenCoordinator)
                        
                        print("x")
                    }){
                        Text("Add Climb")
                            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 5, maxHeight: 10)
                            .font(.title)
                            .padding()
                            .background(Color.yellow)
                            .foregroundColor(.white)
                            .padding(10)
                            .border(Color.yellow, width: 5).cornerRadius(8)
                    }
                    Spacer()
                }
            }
        }.navigationBarTitle("Add a Climb", displayMode:.inline).sheet(isPresented: $showingImagePicker, onDismiss: loadImage) {
            ImagePicker(image: self.$inputImage)
        }
        
        
    }
    func loadImage() {
        guard let inputImage = inputImage else { return }
        image = Image(uiImage: inputImage)
    }
    
}

Upvotes: 4

Views: 2655

Answers (1)

Asperi
Asperi

Reputation: 257493

It is not all components present, but it could be like the following

    }.navigationBarTitle("Add a Climb", displayMode:.inline).sheet(isPresented: $showingImagePicker, onDismiss: loadImage) {
        ImagePicker(image: self.$inputImage)
    }
    .overlay(Group {
       if self.progress.isUploading {          
          ProgressIndicator(progress: self.progress) // << here !!
       }
    })

Upvotes: 4

Related Questions