如何使用完成处理程序将图像放入 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
出现时它会调用getProfilePicture
。 image 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()
}
}
我试过了,但我不知道如何在 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
出现时它会调用getProfilePicture
。 image 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()
}
}