Fix the issue for AnimatedImage when url is nil will not cause the reloading
This commit is contained in:
parent
4c4b868b79
commit
6ba07e3c18
|
@ -18,7 +18,7 @@ class UserSettings: ObservableObject {
|
|||
}
|
||||
|
||||
// Test Switching nil url
|
||||
struct ContentView: View {
|
||||
struct ContentView3: View {
|
||||
@State var isOn = false
|
||||
@State var animated: Bool = false // You can change between WebImage/AnimatedImage
|
||||
|
||||
|
@ -100,7 +100,7 @@ struct ContentView2: View {
|
|||
}
|
||||
}
|
||||
|
||||
struct ContentView3: View {
|
||||
struct ContentView: View {
|
||||
@State var imageURLs = [
|
||||
"http://assets.sbnation.com/assets/2512203/dogflops.gif",
|
||||
"https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif",
|
||||
|
|
|
@ -27,6 +27,13 @@ public final class AnimatedImageCoordinator: NSObject {
|
|||
/// Data Binding Object, only properties in this object can support changes from user with @State and refresh
|
||||
@available(iOS 14.0, OSX 11.0, tvOS 14.0, watchOS 7.0, *)
|
||||
final class AnimatedImageModel : ObservableObject {
|
||||
enum Kind {
|
||||
case url
|
||||
case data
|
||||
case name
|
||||
case unknown
|
||||
}
|
||||
var kind: Kind = .unknown
|
||||
/// URL image
|
||||
@Published var url: URL?
|
||||
@Published var webOptions: SDWebImageOptions = []
|
||||
|
@ -123,6 +130,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
/// - Parameter isAnimating: The binding for animation control
|
||||
public init(url: URL?, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil, isAnimating: Binding<Bool> = .constant(true), placeholderImage: PlatformImage? = nil) {
|
||||
let imageModel = AnimatedImageModel()
|
||||
imageModel.kind = .url
|
||||
imageModel.url = url
|
||||
imageModel.webOptions = options
|
||||
imageModel.webContext = context
|
||||
|
@ -138,6 +146,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
/// - Parameter isAnimating: The binding for animation control
|
||||
public init<T>(url: URL?, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil, isAnimating: Binding<Bool> = .constant(true), @ViewBuilder placeholder: @escaping () -> T) where T : View {
|
||||
let imageModel = AnimatedImageModel()
|
||||
imageModel.kind = .url
|
||||
imageModel.url = url
|
||||
imageModel.webOptions = options
|
||||
imageModel.webContext = context
|
||||
|
@ -157,6 +166,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
/// - Parameter isAnimating: The binding for animation control
|
||||
public init(name: String, bundle: Bundle? = nil, isAnimating: Binding<Bool> = .constant(true)) {
|
||||
let imageModel = AnimatedImageModel()
|
||||
imageModel.kind = .name
|
||||
imageModel.name = name
|
||||
imageModel.bundle = bundle
|
||||
self.init(imageModel: imageModel, isAnimating: isAnimating)
|
||||
|
@ -168,6 +178,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
/// - Parameter isAnimating: The binding for animation control
|
||||
public init(data: Data, scale: CGFloat = 1, isAnimating: Binding<Bool> = .constant(true)) {
|
||||
let imageModel = AnimatedImageModel()
|
||||
imageModel.kind = .data
|
||||
imageModel.data = data
|
||||
imageModel.scale = scale
|
||||
self.init(imageModel: imageModel, isAnimating: isAnimating)
|
||||
|
@ -275,10 +286,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
return view
|
||||
}
|
||||
|
||||
func updateView(_ view: AnimatedImageViewWrapper, context: Context) {
|
||||
// Refresh image, imageModel is the Source of Truth, switch the type
|
||||
// Although we have Source of Truth, we can check the previous value, to avoid re-generate SDAnimatedImage, which is performance-cost.
|
||||
if let name = imageModel.name, name != context.coordinator.imageLoading.imageName {
|
||||
private func updateViewForName(_ name: String, view: AnimatedImageViewWrapper, context: Context) {
|
||||
var image: PlatformImage?
|
||||
#if os(macOS)
|
||||
image = SDAnimatedImage(named: name, in: imageModel.bundle)
|
||||
|
@ -296,7 +304,9 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
#endif
|
||||
context.coordinator.imageLoading.imageName = name
|
||||
view.wrapped.image = image
|
||||
} else if let data = imageModel.data, data != context.coordinator.imageLoading.imageData {
|
||||
}
|
||||
|
||||
private func updateViewForData(_ data: Data, view: AnimatedImageViewWrapper, context: Context) {
|
||||
var image: PlatformImage? = SDAnimatedImage(data: data, scale: imageModel.scale)
|
||||
if image == nil {
|
||||
// For static image, use UIImage as defaults
|
||||
|
@ -304,7 +314,9 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
}
|
||||
context.coordinator.imageLoading.imageData = data
|
||||
view.wrapped.image = image
|
||||
} else if let url = imageModel.url {
|
||||
}
|
||||
|
||||
private func updateViewForURL(_ url: URL?, view: AnimatedImageViewWrapper, context: Context) {
|
||||
// Determine if image already been loaded and URL is match
|
||||
var shouldLoad: Bool
|
||||
if url != context.coordinator.imageLoading.imageURL {
|
||||
|
@ -328,6 +340,20 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
}
|
||||
}
|
||||
|
||||
func updateView(_ view: AnimatedImageViewWrapper, context: Context) {
|
||||
// Refresh image, imageModel is the Source of Truth, switch the type
|
||||
// Although we have Source of Truth, we can check the previous value, to avoid re-generate SDAnimatedImage, which is performance-cost.
|
||||
let kind = imageModel.kind
|
||||
if kind == .name, let name = imageModel.name, name != context.coordinator.imageLoading.imageName {
|
||||
updateViewForName(name, view: view, context: context)
|
||||
} else if kind == .data, let data = imageModel.data, data != context.coordinator.imageLoading.imageData {
|
||||
updateViewForData(data, view: view, context: context)
|
||||
} else if kind == .url {
|
||||
updateViewForURL(imageModel.url, view: view, context: context)
|
||||
} else {
|
||||
fatalError("Unsupported model kind: \(kind)")
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
if self.isAnimating != view.wrapped.animates {
|
||||
view.wrapped.animates = self.isAnimating
|
||||
|
|
Loading…
Reference in New Issue