#swift #swiftui #kingfisher
#swift #swiftui #kingfisher
Вопрос:
Извините за вопрос новичка, я пытаюсь перейти с UIKit на SwiftUI. didSet переменной @State не запускается, как в UIKit.
У меня есть KFImage, который загружает изображение из пользовательского photoUrl, и я хочу, чтобы оно при нажатии запускало средство выбора изображений, а затем обновляло userUIImage
, но поскольку KFImage нуждается в обновлении URL-адреса, я не уверен, как я могу вызвать my 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)
}
}
}
}
Ответ №1:
Попробуйте использовать 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()
}
Комментарии:
1. Привет, спасибо за ваш ответ. Запуск .onChange решил это для меня. Я отредактировал ваш ответ на то, что на самом деле сработало для меня, поскольку
isImageLoaded
было неправильно использовано. Хотя это моя вина, я должен был назвать егоisImageInitiallyLoaded
вместо этого