Home > OS >  Save photo SwiftUI
Save photo SwiftUI

Time:01-20

Here I get the image from the link

struct CustomImageView: View {
    var urlString: String
    @ObservedObject var imageLoader = ImageLoaderService()
    @State var image: UIImage = UIImage()
    
    var body: some View {
        Image(uiImage: image)
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(width:100, height:100)
            .onReceive(imageLoader.$image) { image in
                self.image = image
            }
            .onAppear {
                imageLoader.loadImage(for: urlString)
            }
    }
}

class ImageLoaderService: ObservableObject {
    @Published var image: UIImage = UIImage()
    
    func loadImage(for urlString: String) {
        guard let url = URL(string: urlString) else { return }
        
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else { return }
            DispatchQueue.main.async {
                self.image = UIImage(data: data) ?? UIImage()
            }
        }
        task.resume()
    }
    
}

Here I display the received photo by the link and try to save it via .contextMenu

  VStack {

            CustomImageView(urlString: "https://stackoverflow.design/assets/img/logos/so/logo-stackoverflow.png")
                .contextMenu {
                    
                  Button(action: {
 
                    }) {
                        HStack {
                            
                            Text("Save image")
                            Image(systemName: "square.and.arrow.down.fill")
                            
                        }
                    }
                }
            }

When you click on a photo, a .contextMenu opens with a save button, but the photo is not saved, what should I do?

CodePudding user response:

in your button action add

UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)

where image is a UIImage, so you need to pass the image from your model and pass it to the above snippet.

Full Code:

struct CustomImageView: View {
    var urlString: String
    @ObservedObject var imageLoader: ImageLoaderService
    @State var image: UIImage = UIImage()
    var body: some View {
        Image(uiImage: image)
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(width:100, height:100)
            .onReceive(imageLoader.$image) { image in
                self.image = image
            }.onAppear {
                imageLoader.loadImage(for: urlString)
            }
    }
}

 class ImageLoaderService: ObservableObject {
    @Published var image: UIImage = UIImage()
    func loadImage(for urlString: String) {
        guard let url = URL(string: urlString) else {return}
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else {return}
            DispatchQueue.main.async {
                self.image = UIImage(data: data) ?? UIImage()
            }
        }
        task.resume()
    }
}

struct ContentView: View {
    @ObservedObject var imageLoader = ImageLoaderService()
    var body: some View {
        VStack {
            CustomImageView(urlString: "https://stackoverflow.design/assets/img/logos/so/logo-stackoverflow.png", imageLoader: imageLoader)
                .contextMenu {
                    Button(action: {
                        UIImageWriteToSavedPhotosAlbum(imageLoader.image, nil, nil, nil)
                    }) {
                        HStack {
                            Text("Save image")
                            Image(systemName: "square.and.arrow.down.fill")

                        }
                    }
                }
        }
    }
}
  •  Tags:  
  • Related