diff --git a/README.md b/README.md index f087f55b..24c90e7e 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ var body: some View { - [x] Supports animation control using the SwiftUI Binding - [x] Supports indicator and transition powered by SDWebImage and CoreAnimation - [x] Supports advanced control like loop count, incremental load, buffer size +- [x] Supports coordinate with native UIKit/AppKit/WKInterface view Note: `AnimatedImage` supports both image url or image data for animated image format. Which use the SDWebImage's [Animated ImageView](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#animated-image-50) for internal implementation. Pay attention that since this base on UIKit/AppKit representable, if you need advanced customized layout and animation, you need CoreAnimation to help. diff --git a/SDWebImageSwiftUI/Classes/AnimatedImage.swift b/SDWebImageSwiftUI/Classes/AnimatedImage.swift index 9950150f..8475f930 100644 --- a/SDWebImageSwiftUI/Classes/AnimatedImage.swift +++ b/SDWebImageSwiftUI/Classes/AnimatedImage.swift @@ -20,6 +20,12 @@ final class AnimatedImageModel : ObservableObject { @Published var progressBlock: ((Int, Int) -> Void)? } +// Coordinator Life Cycle Binding Object +final class AnimatedImageCoordinator : ObservableObject { + @Published var viewCreateBlock: ((PlatformView) -> Void)? + @Published var viewUpdateBlock: ((PlatformView) -> Void)? +} + // Layout Binding Object final class AnimatedImageLayout : ObservableObject { @Published var contentMode: ContentMode = .fill @@ -58,6 +64,7 @@ public struct AnimatedImage : PlatformViewRepresentable { @ObservedObject var imageModel = AnimatedImageModel() @ObservedObject var imageLayout = AnimatedImageLayout() @ObservedObject var imageConfiguration = AnimatedImageConfiguration() + @ObservedObject var imageCoordinator = AnimatedImageCoordinator() var url: URL? var placeholder: PlatformImage? @@ -196,7 +203,11 @@ public struct AnimatedImage : PlatformViewRepresentable { } func makeView(context: PlatformViewRepresentableContext) -> AnimatedImageViewWrapper { - AnimatedImageViewWrapper() + let view = AnimatedImageViewWrapper() + if let viewCreateBlock = imageCoordinator.viewCreateBlock { + viewCreateBlock(view) + } + return view } func updateView(_ view: AnimatedImageViewWrapper, context: PlatformViewRepresentableContext) { @@ -238,6 +249,9 @@ public struct AnimatedImage : PlatformViewRepresentable { configureView(view, context: context) layoutView(view, context: context) + if let viewUpdateBlock = imageCoordinator.viewUpdateBlock { + viewUpdateBlock(view) + } } static func dismantleView(_ view: AnimatedImageViewWrapper, coordinator: ()) { @@ -554,6 +568,26 @@ extension AnimatedImage { } } +// View Coordinator Handler +extension AnimatedImage { + + /// Provide the action when view representable create the native view. + /// - Parameter action: The action to perform. The first arg is the native view. + /// - Returns: A view that triggers `action` when view representable create the native view. + public func onViewCreate(perform action: ((PlatformView) -> Void)? = nil) -> AnimatedImage { + imageCoordinator.viewCreateBlock = action + return self + } + + /// Provide the action when view representable update the native view. + /// - Parameter action: The action to perform. The first arg is the native view. + /// - Returns: A view that triggers `action` when view representable update the native view. + public func onViewUpdate(perform action: ((PlatformView) -> Void)? = nil) -> AnimatedImage { + imageCoordinator.viewUpdateBlock = action + return self + } +} + #if os(macOS) || os(iOS) || os(tvOS) // Web Image convenience extension AnimatedImage { diff --git a/SDWebImageSwiftUI/Classes/Indicator/Indicator.swift b/SDWebImageSwiftUI/Classes/Indicator/Indicator.swift index f52b37e0..9e67a29c 100644 --- a/SDWebImageSwiftUI/Classes/Indicator/Indicator.swift +++ b/SDWebImageSwiftUI/Classes/Indicator/Indicator.swift @@ -25,7 +25,7 @@ public struct Indicator { } } -#if os(macOS) || os(iOS) || os(iOS) +#if os(macOS) || os(iOS) || os(tvOS) extension Indicator { /// Activity Indicator public static var activity: Indicator {