Kingfisher 更新 KFImage url 未更新 SwiftUI 中的图像
Kingfisher updating KFImage url is not updating the image in SwiftUI
抱歉初学者问题,我正在尝试从 UIKit 过渡到 SwiftUI。 @State 变量的 didSet 不会像在 UIKit 中那样被触发。
我有 KFImage 从用户的 photoUrl 加载图像,点击时我想要它,启动图像选择器,然后更新 userUIImage
但由于 KFImage 需要更新 url,我我不确定如何调用我的 updateUserImage()
来更新 photoUrl 以更新 KFImage。
下面是我的代码
struct ProfileView: View {
//MARK: Properties
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
@State private var isImageLoaded: Bool = false
@State private var showImagePicker = false
@State private var photoUrl: URL? = URL(string: (Customer.current?.photoUrl)!)
@State private var userImage: Image? = Image(uiImage: UIImage())
@State private var userUIImage: UIImage? = UIImage() {
didSet {
if isImageLoaded {
updateUserImage()
}
}
}
var body: some View {
KFImage(photoUrl)
.resizable()
.onSuccess { result in
self.userUIImage = result.image
self.isImageLoaded = true
}
.aspectRatio(contentMode: .fill)
.frame(width: screenWidth / 2.5)
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWidth: 4))
.shadow(radius: 10)
.onTapGesture { self.showImagePicker = true }
.sheet(isPresented: $showImagePicker) {
CustomImagePickerView(sourceType: .photoLibrary, image: $userImage, uiImage: $userUIImage, isPresented: $showImagePicker)
}
}
//MARK: Methods
func updateUserImage() {
CustomerService.updateUserImage(image: userUIImage!) { (photoUrl, error) in
if let error = error {
handleError(errorBody: error)
return
}
guard var user = Customer.current else { return }
self.photoUrl = photoUrl
user.photoUrl = photoUrl?.absoluteString
CustomerService.updateUserDatabase(user: user) { (error) in
if let error = error {
handleError(errorBody: error)
return
}
Customer.setCurrent(user, writeToUserDefaults: true)
}
}
}
}
尝试使用 onChange
/ onReceive
代替:
KFImage(photoUrl)
.resizable()
// ...
// remove .onSuccess implementation as self.userUIImage = result.image will result in an infinite loop
.onChange(of: userUIImage) { newImage in
updateUserImage()
}
或
import Combine
...
KFImage(photoUrl)
.resizable()
// ...
.onReceive(Just(userUIImage)) { newImage in
updateUserImage()
}
抱歉初学者问题,我正在尝试从 UIKit 过渡到 SwiftUI。 @State 变量的 didSet 不会像在 UIKit 中那样被触发。
我有 KFImage 从用户的 photoUrl 加载图像,点击时我想要它,启动图像选择器,然后更新 userUIImage
但由于 KFImage 需要更新 url,我我不确定如何调用我的 updateUserImage()
来更新 photoUrl 以更新 KFImage。
下面是我的代码
struct ProfileView: View {
//MARK: Properties
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
@State private var isImageLoaded: Bool = false
@State private var showImagePicker = false
@State private var photoUrl: URL? = URL(string: (Customer.current?.photoUrl)!)
@State private var userImage: Image? = Image(uiImage: UIImage())
@State private var userUIImage: UIImage? = UIImage() {
didSet {
if isImageLoaded {
updateUserImage()
}
}
}
var body: some View {
KFImage(photoUrl)
.resizable()
.onSuccess { result in
self.userUIImage = result.image
self.isImageLoaded = true
}
.aspectRatio(contentMode: .fill)
.frame(width: screenWidth / 2.5)
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWidth: 4))
.shadow(radius: 10)
.onTapGesture { self.showImagePicker = true }
.sheet(isPresented: $showImagePicker) {
CustomImagePickerView(sourceType: .photoLibrary, image: $userImage, uiImage: $userUIImage, isPresented: $showImagePicker)
}
}
//MARK: Methods
func updateUserImage() {
CustomerService.updateUserImage(image: userUIImage!) { (photoUrl, error) in
if let error = error {
handleError(errorBody: error)
return
}
guard var user = Customer.current else { return }
self.photoUrl = photoUrl
user.photoUrl = photoUrl?.absoluteString
CustomerService.updateUserDatabase(user: user) { (error) in
if let error = error {
handleError(errorBody: error)
return
}
Customer.setCurrent(user, writeToUserDefaults: true)
}
}
}
}
尝试使用 onChange
/ onReceive
代替:
KFImage(photoUrl)
.resizable()
// ...
// remove .onSuccess implementation as self.userUIImage = result.image will result in an infinite loop
.onChange(of: userUIImage) { newImage in
updateUserImage()
}
或
import Combine
...
KFImage(photoUrl)
.resizable()
// ...
.onReceive(Just(userUIImage)) { newImage in
updateUserImage()
}