Using a more trick but smart solution for cases when WebImage is used during transition state, like scaleEffect. In this time, we does not trigger a actualy image loading, only query the memory cache for quickly placeholder
This commit is contained in:
parent
0b11cceaaa
commit
d9fd4726ea
|
@ -38,7 +38,7 @@ struct DetailView: View {
|
|||
let url: String
|
||||
let animated: Bool
|
||||
@State var isAnimating: Bool = true
|
||||
@State var lastScaleValue: CGFloat = 1.0
|
||||
@State var lastScale: CGFloat = 1.0
|
||||
@State var scale: CGFloat = 1.0
|
||||
@Environment(\.presentationMode) var presentationMode
|
||||
@EnvironmentObject var settings: UserSettings
|
||||
|
@ -75,12 +75,12 @@ struct DetailView: View {
|
|||
return contentView()
|
||||
.scaleEffect(self.scale)
|
||||
.gesture(MagnificationGesture(minimumScaleDelta: 0.1).onChanged { value in
|
||||
let delta = value / self.lastScaleValue
|
||||
self.lastScaleValue = value
|
||||
let delta = value / self.lastScale
|
||||
self.lastScale = value
|
||||
let newScale = self.scale * delta
|
||||
self.scale = min(max(newScale, 0.5), 2)
|
||||
}.onEnded { value in
|
||||
self.lastScaleValue = 1.0
|
||||
self.lastScale = 1.0
|
||||
})
|
||||
#endif
|
||||
#if os(tvOS)
|
||||
|
|
|
@ -106,6 +106,23 @@ public final class ImageManager : ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
/// Prefetch the initial state of image
|
||||
internal func prefetch() {
|
||||
let key = manager.cacheKey(for: url)
|
||||
if let imageCache = manager.imageCache as? SDImageCache {
|
||||
self.image = imageCache.imageFromMemoryCache(forKey: key)
|
||||
} else {
|
||||
// generic API
|
||||
manager.imageCache.containsImage(forKey: key, cacheType: .memory) { [unowned self] (cacheType) in
|
||||
if cacheType == .memory {
|
||||
self.manager.imageCache.queryImage(forKey: key, options: self.options, context: self.context) { [unowned self] (image, data, cacheType) in
|
||||
self.image = image
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Completion Handler
|
||||
|
|
|
@ -57,16 +57,13 @@ public struct WebImage : View {
|
|||
}
|
||||
}
|
||||
self.imageManager = ImageManager(url: url, options: options, context: context)
|
||||
// this prefetch the memory cache of image, to immediately render it on screen
|
||||
// this solve the cause when `onAppear` not been called, for example, some transaction indetermite state :)
|
||||
self.imageManager.prefetch()
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
// load remote image when first called `body`, SwiftUI sometimes will create a new View struct without calling `onAppear` (like enter EditMode) :)
|
||||
// this can ensure we load the image, and display image synchronously when memory cache hit to avoid flashing
|
||||
// called once per struct, SDWebImage take care of the duplicated query
|
||||
if imageManager.isFirstLoad {
|
||||
imageManager.load()
|
||||
}
|
||||
return Group {
|
||||
Group {
|
||||
if imageManager.image != nil {
|
||||
if isAnimating && !self.imageManager.isIncremental {
|
||||
if currentFrame != nil {
|
||||
|
@ -109,6 +106,11 @@ public struct WebImage : View {
|
|||
setupPlaceholder()
|
||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
||||
.onAppear {
|
||||
// load remote image when first appear
|
||||
if self.imageManager.isFirstLoad {
|
||||
self.imageManager.load()
|
||||
return
|
||||
}
|
||||
guard self.retryOnAppear else { return }
|
||||
// When using prorgessive loading, the new partial image will cause onAppear. Filter this case
|
||||
if self.imageManager.image == nil && !self.imageManager.isIncremental {
|
||||
|
|
Loading…
Reference in New Issue