【问题标题】:How to use a completion handler to put an image in a SwiftUI view如何使用完成处理程序将图像放入 SwiftUI 视图
【发布时间】:2020-02-20 08:32:38
【问题描述】:

我已经尝试过了,但我不知道如何在 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)

        }
    }
}

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

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)
    }

}

}

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

【问题讨论】:

  • return image 所在的行放置一个断点。这是什么?
  • @Adrian 你是什么意思?
  • 看看这个:youtube.com/watch?v=mgspBMsWlS4。类型。 po image 在你抛出一个断点之后看看它是什么。
  • 另外,看看这篇文章中的struct ImageProvider: RequestImages部分。 medium.com/better-programming/…
  • 我认为您应该接受答案并提出另一个问题。您扩大了原始问题的范围。 TBQH,我没怎么玩过 SwiftUI,所以那里没有权威的答案。

标签: swift swiftui swift5 completionhandler


【解决方案1】:

你可以试试这个:

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(image))。然后您可以做的是将您的placeHolderImage 更改为您在getProfilePicture 中获得的内容,但在您这样做之前,您需要将您的uiImage 设置为Image。还要确保将 @State 关键字添加到变量中,这样一旦它发生更改,您的 View 就会更新。

希望有帮助!

【讨论】:

    【解决方案2】:

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

    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)
    
                }
            }
        }
    

    【讨论】:

    • 我以前试过这个,但是在 SwiftUI 视图中使用完成结果很难
    • @EliFront 我无法提供确切的解决方案,因为到目前为止我还没有使用过SwiftUI。但我认为您将需要一些State 变量并将您的Image 绑定到该变量,稍后一旦您完成UIImage,只需设置State 变量,以便您的Image 可以更新。您也可以查看link
    • 太糟糕了,因为我觉得我很亲近。我只需要弄清楚如何从不返回视图的 swiftUI 视图中调用函数
    【解决方案3】:
    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()
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 2020-09-19
      • 1970-01-01
      • 2021-07-09
      • 1970-01-01
      相关资源
      最近更新 更多