Add the same overload method for onSuccess API, which introduce the image data arg. Keep the source code compatibility
This commit is contained in:
parent
8a347dc4dc
commit
b174fee26b
|
@ -111,8 +111,9 @@ github "SDWebImage/SDWebImageSwiftUI"
|
||||||
var body: some View {
|
var body: some View {
|
||||||
WebImage(url: URL(string: "https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic"))
|
WebImage(url: URL(string: "https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic"))
|
||||||
// Supports options and context, like `.delayPlaceholder` to show placeholder only when error
|
// Supports options and context, like `.delayPlaceholder` to show placeholder only when error
|
||||||
.onSuccess { image, cacheType in
|
.onSuccess { image, data, cacheType in
|
||||||
// Success
|
// Success
|
||||||
|
// Note: Data exist only when queried from disk cache or network. Use `.queryMemoryData` if you really need data
|
||||||
}
|
}
|
||||||
.resizable() // Resizable like SwiftUI.Image, you must use this modifier or the view will use the image bitmap size
|
.resizable() // Resizable like SwiftUI.Image, you must use this modifier or the view will use the image bitmap size
|
||||||
.placeholder(Image(systemName: "photo")) // Placeholder Image
|
.placeholder(Image(systemName: "photo")) // Placeholder Image
|
||||||
|
|
|
@ -49,7 +49,7 @@ final class AnimatedLoadingModel : ObservableObject, IndicatorReportable {
|
||||||
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
|
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
|
||||||
final class AnimatedImageHandler: ObservableObject {
|
final class AnimatedImageHandler: ObservableObject {
|
||||||
// Completion Handler
|
// Completion Handler
|
||||||
@Published var successBlock: ((PlatformImage, SDImageCacheType) -> Void)?
|
@Published var successBlock: ((PlatformImage, Data?, SDImageCacheType) -> Void)?
|
||||||
@Published var failureBlock: ((Error) -> Void)?
|
@Published var failureBlock: ((Error) -> Void)?
|
||||||
@Published var progressBlock: ((Int, Int) -> Void)?
|
@Published var progressBlock: ((Int, Int) -> Void)?
|
||||||
// Coordinator Handler
|
// Coordinator Handler
|
||||||
|
@ -208,12 +208,15 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.imageLoading.isLoading = true
|
self.imageLoading.isLoading = true
|
||||||
if imageModel.webOptions.contains(.delayPlaceholder) {
|
let options = imageModel.webOptions
|
||||||
|
if options.contains(.delayPlaceholder) {
|
||||||
self.imageConfiguration.placeholderView?.isHidden = true
|
self.imageConfiguration.placeholderView?.isHidden = true
|
||||||
} else {
|
} else {
|
||||||
self.imageConfiguration.placeholderView?.isHidden = false
|
self.imageConfiguration.placeholderView?.isHidden = false
|
||||||
}
|
}
|
||||||
view.wrapped.sd_setImage(with: imageModel.url, placeholderImage: imageConfiguration.placeholder, options: imageModel.webOptions, context: imageModel.webContext, progress: { (receivedSize, expectedSize, _) in
|
var context = imageModel.webContext ?? [:]
|
||||||
|
context[.animatedImageClass] = SDAnimatedImage.self
|
||||||
|
view.wrapped.sd_internalSetImage(with: imageModel.url, placeholderImage: imageConfiguration.placeholder, options: options, context: context, setImageBlock: nil, progress: { (receivedSize, expectedSize, _) in
|
||||||
let progress: Double
|
let progress: Double
|
||||||
if (expectedSize > 0) {
|
if (expectedSize > 0) {
|
||||||
progress = Double(receivedSize) / Double(expectedSize)
|
progress = Double(receivedSize) / Double(expectedSize)
|
||||||
|
@ -224,7 +227,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
||||||
self.imageLoading.progress = progress
|
self.imageLoading.progress = progress
|
||||||
}
|
}
|
||||||
self.imageHandler.progressBlock?(receivedSize, expectedSize)
|
self.imageHandler.progressBlock?(receivedSize, expectedSize)
|
||||||
}) { (image, error, cacheType, _) in
|
}) { (image, data, error, cacheType, finished, _) in
|
||||||
// This is a hack because of Xcode 11.3 bug, the @Published does not trigger another `updateUIView` call
|
// This is a hack because of Xcode 11.3 bug, the @Published does not trigger another `updateUIView` call
|
||||||
// Here I have to use UIKit/AppKit API to triger the same effect (the window change implicitly cause re-render)
|
// Here I have to use UIKit/AppKit API to triger the same effect (the window change implicitly cause re-render)
|
||||||
if let hostingView = AnimatedImage.findHostingView(from: view) {
|
if let hostingView = AnimatedImage.findHostingView(from: view) {
|
||||||
|
@ -241,7 +244,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
||||||
self.imageLoading.progress = 1
|
self.imageLoading.progress = 1
|
||||||
if let image = image {
|
if let image = image {
|
||||||
self.imageConfiguration.placeholderView?.isHidden = true
|
self.imageConfiguration.placeholderView?.isHidden = true
|
||||||
self.imageHandler.successBlock?(image, cacheType)
|
self.imageHandler.successBlock?(image, data, cacheType)
|
||||||
} else {
|
} else {
|
||||||
self.imageConfiguration.placeholderView?.isHidden = false
|
self.imageConfiguration.placeholderView?.isHidden = false
|
||||||
self.imageHandler.failureBlock?(error ?? NSError())
|
self.imageHandler.failureBlock?(error ?? NSError())
|
||||||
|
@ -702,11 +705,33 @@ extension AnimatedImage {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Provide the action when image load successes.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - action: The action to perform. The first arg is the loaded image. If `action` is `nil`, the call has no effect.
|
||||||
|
/// - Returns: A view that triggers `action` when this image load successes.
|
||||||
|
public func onSuccess(perform action: @escaping (PlatformImage) -> Void) -> AnimatedImage {
|
||||||
|
self.imageHandler.successBlock = { image, _, _ in
|
||||||
|
action(image)
|
||||||
|
}
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
/// Provide the action when image load successes.
|
/// Provide the action when image load successes.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - action: The action to perform. The first arg is the loaded image, the second arg is the cache type loaded from. If `action` is `nil`, the call has no effect.
|
/// - action: The action to perform. The first arg is the loaded image, the second arg is the cache type loaded from. If `action` is `nil`, the call has no effect.
|
||||||
/// - Returns: A view that triggers `action` when this image load successes.
|
/// - Returns: A view that triggers `action` when this image load successes.
|
||||||
public func onSuccess(perform action: ((PlatformImage, SDImageCacheType) -> Void)? = nil) -> AnimatedImage {
|
public func onSuccess(perform action: @escaping (PlatformImage, SDImageCacheType) -> Void) -> AnimatedImage {
|
||||||
|
self.imageHandler.successBlock = { image, _, cacheType in
|
||||||
|
action(image, cacheType)
|
||||||
|
}
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provide the action when image load successes.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - action: The action to perform. The first arg is the loaded image, the second arg is the loaded image data, the third arg is the cache type loaded from. If `action` is `nil`, the call has no effect.
|
||||||
|
/// - Returns: A view that triggers `action` when this image load successes.
|
||||||
|
public func onSuccess(perform action: ((PlatformImage, Data?, SDImageCacheType) -> Void)? = nil) -> AnimatedImage {
|
||||||
self.imageHandler.successBlock = action
|
self.imageHandler.successBlock = action
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ public final class ImageManager : ObservableObject {
|
||||||
@Published public var image: PlatformImage?
|
@Published public var image: PlatformImage?
|
||||||
/// loaded image data, may be nil if hit from memory cache. This will only published once even on incremental image loading
|
/// loaded image data, may be nil if hit from memory cache. This will only published once even on incremental image loading
|
||||||
@Published public var imageData: Data?
|
@Published public var imageData: Data?
|
||||||
|
/// loaded image cache type, .none means from network
|
||||||
|
@Published public var cacheType: SDImageCacheType = .none
|
||||||
/// loading error, you can grab the error code and reason listed in `SDWebImageErrorDomain`, to provide a user interface about the error reason
|
/// loading error, you can grab the error code and reason listed in `SDWebImageErrorDomain`, to provide a user interface about the error reason
|
||||||
@Published public var error: Error?
|
@Published public var error: Error?
|
||||||
/// whether network is loading or cache is querying, should only be used for indicator binding
|
/// whether network is loading or cache is querying, should only be used for indicator binding
|
||||||
|
@ -33,7 +35,7 @@ public final class ImageManager : ObservableObject {
|
||||||
var url: URL?
|
var url: URL?
|
||||||
var options: SDWebImageOptions
|
var options: SDWebImageOptions
|
||||||
var context: [SDWebImageContextOption : Any]?
|
var context: [SDWebImageContextOption : Any]?
|
||||||
var successBlock: ((PlatformImage, SDImageCacheType) -> Void)?
|
var successBlock: ((PlatformImage, Data?, SDImageCacheType) -> Void)?
|
||||||
var failureBlock: ((Error) -> Void)?
|
var failureBlock: ((Error) -> Void)?
|
||||||
var progressBlock: ((Int, Int) -> Void)?
|
var progressBlock: ((Int, Int) -> Void)?
|
||||||
|
|
||||||
|
@ -89,10 +91,11 @@ public final class ImageManager : ObservableObject {
|
||||||
self.isIncremental = !finished
|
self.isIncremental = !finished
|
||||||
if finished {
|
if finished {
|
||||||
self.imageData = data
|
self.imageData = data
|
||||||
|
self.cacheType = cacheType
|
||||||
self.isLoading = false
|
self.isLoading = false
|
||||||
self.progress = 1
|
self.progress = 1
|
||||||
if let image = image {
|
if let image = image {
|
||||||
self.successBlock?(image, cacheType)
|
self.successBlock?(image, data, cacheType)
|
||||||
} else {
|
} else {
|
||||||
self.failureBlock?(error ?? NSError())
|
self.failureBlock?(error ?? NSError())
|
||||||
}
|
}
|
||||||
|
@ -120,10 +123,28 @@ extension ImageManager {
|
||||||
self.failureBlock = action
|
self.failureBlock = action
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Provide the action when image load successes.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - action: The action to perform. The first arg is the loaded image. If `action` is `nil`, the call has no effect.
|
||||||
|
public func setOnSuccess(perform action: @escaping (PlatformImage) -> Void) {
|
||||||
|
self.successBlock = { image, _, _ in
|
||||||
|
action(image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Provide the action when image load successes.
|
/// Provide the action when image load successes.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - action: The action to perform. The first arg is the loaded image, the second arg is the cache type loaded from. If `action` is `nil`, the call has no effect.
|
/// - action: The action to perform. The first arg is the loaded image, the second arg is the cache type loaded from. If `action` is `nil`, the call has no effect.
|
||||||
public func setOnSuccess(perform action: ((PlatformImage, SDImageCacheType) -> Void)? = nil) {
|
public func setOnSuccess(perform action: @escaping (PlatformImage, SDImageCacheType) -> Void) {
|
||||||
|
self.successBlock = { image, _, cacheType in
|
||||||
|
action(image, cacheType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provide the action when image load successes.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - action: The action to perform. The first arg is the loaded image, the second arg is the loaded image data, the third arg is the cache type loaded from. If `action` is `nil`, the call has no effect.
|
||||||
|
public func setOnSuccess(perform action: ((PlatformImage, Data?, SDImageCacheType) -> Void)? = nil) {
|
||||||
self.successBlock = action
|
self.successBlock = action
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -264,11 +264,34 @@ extension WebImage {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Provide the action when image load successes.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - action: The action to perform. The first arg is the loaded image. If `action` is `nil`, the call has no effect.
|
||||||
|
/// - Returns: A view that triggers `action` when this image load successes.
|
||||||
|
public func onSuccess(perform action: @escaping (PlatformImage) -> Void) -> WebImage {
|
||||||
|
let action = action
|
||||||
|
self.imageManager.successBlock = { image, _, _ in
|
||||||
|
action(image)
|
||||||
|
}
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
/// Provide the action when image load successes.
|
/// Provide the action when image load successes.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - action: The action to perform. The first arg is the loaded image, the second arg is the cache type loaded from. If `action` is `nil`, the call has no effect.
|
/// - action: The action to perform. The first arg is the loaded image, the second arg is the cache type loaded from. If `action` is `nil`, the call has no effect.
|
||||||
/// - Returns: A view that triggers `action` when this image load successes.
|
/// - Returns: A view that triggers `action` when this image load successes.
|
||||||
public func onSuccess(perform action: ((PlatformImage, SDImageCacheType) -> Void)? = nil) -> WebImage {
|
public func onSuccess(perform action: @escaping (PlatformImage, SDImageCacheType) -> Void) -> WebImage {
|
||||||
|
self.imageManager.successBlock = { image, _, cacheType in
|
||||||
|
action(image, cacheType)
|
||||||
|
}
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provide the action when image load successes.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - action: The action to perform. The first arg is the loaded image, the second arg is the loaded image data, the third arg is the cache type loaded from. If `action` is `nil`, the call has no effect.
|
||||||
|
/// - Returns: A view that triggers `action` when this image load successes.
|
||||||
|
public func onSuccess(perform action: ((PlatformImage, Data?, SDImageCacheType) -> Void)? = nil) -> WebImage {
|
||||||
self.imageManager.successBlock = action
|
self.imageManager.successBlock = action
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue