如何使用完成处理程序将图像放入 SwiftUI 视图中

How to use a completion handler to put an image in a SwiftUI view

我试过了,但我不知道如何在 SwiftUI 视图中使用结果:

func getProfilePicture(_ completion: @escaping ((UIImage) -> Void)) {

    Alamofire.request(GIDSignIn.sharedInstance()?.currentUser.profile.imageURL(withDimension: 75) ?? "https://httpbin.org/image/png").responseImage { response in

        if let image = response.result.value {
            completion(image)

        }
    }
}

如果你能帮忙,我想把来自完成处理程序的 returned 图像放在这个视图中:

struct ProfileView: View {
let profileInfo = ProfileInfo()
var placeHolderImage = Image(systemName: "person")

var body: some View {
    Group {
            placeHolderImage
                .clipShape(Circle())
                .overlay(
                    Circle().stroke(Color.white, lineWidth: 4))
                .shadow(radius: 10)
                .padding(10)
    }

}

}

我想 return 一个 UIImage,这样我最终可以在 SwiftUI 视图中使用它。我已经尝试使用带有 @escaping 完成处理程序的方法,但我不知道如何使用它来解决问题。谢谢!

使用如下的完成处理程序,

func getProfilePicture(_ completion: @escaping ((UIImage) -> Void)) {

        Alamofire.request(GIDSignIn.sharedInstance()?.currentUser.profile.imageURL(withDimension: 75) ?? "https://httpbin.org/image/png").responseImage { response in

            if let image = response.result.value {
                completion(image)

            }
        }
    }

你可以试试这个:

struct ProfileView: View {
    @State var placeHolderImage = Image(systemName: "person")


    var body: some View {
        Group {
            placeHolderImage
                .clipShape(Circle())
                .overlay(
                    Circle().stroke(Color.white, lineWidth: 4))
                .shadow(radius: 10)
                .padding(10)
        }.onAppear{
            getProfilePicture{ image in
                self.placeHolderImage = Image(uiImage: image)
            }
        }

    }

}

ProfileView出现时它会调用getProfilePictureimage in中指定的image(调用函数时)是completion handler经过的(completion(image))。然后你可以做的是将你的 placeHolderImage 更改为你在 getProfilePicture 中获得的内容,但在你这样做之前,你需要将你的 uiImage 变成 Image。还要确保将 @State 关键字添加到变量中,这样一旦它发生变化,您的 View 就会更新。

希望对您有所帮助!

import SwiftUI

@available(macCatalyst 14.0, *)
@available(iOS 14.0, *)

struct MyUIView : View {
    
    // MARK: - Properties -
    
    @StateObject var myStore : MyStore = MyStore()
    @State var imgArray : Array<Image> = Array<Image>.init(repeating: Image("no-image"), count: 100)

    // MARK: - View -

    var body : some View {
        
        ScrollView {
                                        
            Text("IMAGES")

            LazyVStack (alignment: .leading, spacing: 8.0) {
                
                // actionPlans
                
                ForEach((0 ..< myStore.data.count).clamped(to: 0..<2), id: \.self) { i in
                    
                    HStack {
                        
                        let url = myStore.data[i]
                                       
                        let img : Image = imgArray[i]
                        
                        img
                            .resizable()
                            .scaledToFit()
                            .frame(width: 50, height: 50, alignment: .leading)
                            .padding(EdgeInsets(top: 0, leading: 0.0, bottom: 0, trailing: 16.0))
                            .onAppear(){
                            
                                imageFrom(url: url, completion: { image in
                                                                    
                                    imgArray[i] = Image(uiImage: image!)
                                                                            
                                })
                                
                            }
                                                    
                    }
                    
                    Divider()
                    
                }
                            
            }
                        
        }.onAppear(perform: {
            
            fetch()
            
        })
                
    }
    
    // MARK: - Media -

    private func fetch() {
        
        DispatchQueue.main.async {
            
            myStore.getData()

        }

    }
    
    func imageFrom(url: String, completion: @escaping (UIImage?) -> Void) {
        
        // image
                                
        if ImageLoader.sharedInstance.checkForImage(url: url as NSString?) {
            
            // has image
            
            completion(ImageLoader.sharedInstance.returnImage(url: url as NSString?)!)
            
        } else {
            
            ImageLoader.sharedInstance.getImage(url: url as NSString?) { (image) in
                                    
                if image != nil {
                    
                    completion(image)
                    
                } else {
                    
                    completion(UIImage.init(named: "no-image"))
                    
                }
                            
            }
            
        }
    }
    
}

@available(macCatalyst 14.0, *)
@available(iOS 14.0, *)

struct MyUIView_Previews: PreviewProvider {

    static var previews: some View {
        MyUIView()
    }

}