Merge pull request #14 from SDWebImage/feature_animatedimage_animating_control
Supports AnimatedImage animation control using of SwiftUI Binding
This commit is contained in:
commit
df7728d894
|
@ -13,6 +13,7 @@ struct DetailView: View {
|
|||
let url: String
|
||||
let animated: Bool
|
||||
@State var progress: CGFloat = 1
|
||||
@State var isAnimating: Bool = true
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
|
@ -24,7 +25,7 @@ struct DetailView: View {
|
|||
Spacer()
|
||||
HStack {
|
||||
if animated {
|
||||
AnimatedImage(url: URL(string:url), options: [.progressiveLoad])
|
||||
AnimatedImage(url: URL(string:url), options: [.progressiveLoad], isAnimating: $isAnimating)
|
||||
.onProgress(perform: { (receivedSize, expectedSize) in
|
||||
// SwiftUI engine itself ensure the main queue dispatch
|
||||
if (expectedSize >= 0) {
|
||||
|
@ -35,6 +36,9 @@ struct DetailView: View {
|
|||
})
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.navigationBarItems(trailing: Button(isAnimating ? "Stop" : "Start") {
|
||||
self.isAnimating.toggle()
|
||||
})
|
||||
} else {
|
||||
WebImage(url: URL(string:url), options: [.progressiveLoad])
|
||||
.onProgress(perform: { (receivedSize, expectedSize) in
|
||||
|
|
10
README.md
10
README.md
|
@ -85,20 +85,24 @@ var body: some View {
|
|||
```swift
|
||||
var body: some View {
|
||||
Group {
|
||||
AnimatedImage(url: URL(string: "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif")) // Network
|
||||
// Network
|
||||
AnimatedImage(url: URL(string: "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif"))
|
||||
.onFailure(perform: { (error) in
|
||||
// Error
|
||||
})
|
||||
.scaledToFit()
|
||||
AnimatedImage(data: try! Data(contentsOf: URL(fileURLWithPath: "/tmp/foo.webp"))) // Data
|
||||
// Data
|
||||
AnimatedImage(data: try! Data(contentsOf: URL(fileURLWithPath: "/tmp/foo.webp")))
|
||||
.customLoopCount(1)
|
||||
AnimatedImage(name: "animation1") // Bundle (not Asset Catalog)
|
||||
// Bundle (not Asset Catalog)
|
||||
AnimatedImage(name: "animation1", isAnimating: $isAnimating)) // Animation control binding
|
||||
.maxBufferSize(.max)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [x] Supports network image as well as local data and bundle image
|
||||
- [x] Supports animation control using the SwiftUI Binding
|
||||
- [x] Supports advanced control like loop count, incremental load, buffer size.
|
||||
|
||||
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.
|
||||
|
|
|
@ -48,6 +48,46 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
var webOptions: SDWebImageOptions = []
|
||||
var webContext: [SDWebImageContextOption : Any]? = nil
|
||||
|
||||
/// A Binding to control the animation. You can bind external logic to control the animation status.
|
||||
/// True to start animation, false to stop animation.
|
||||
@Binding public var isAnimating: Bool
|
||||
|
||||
public init(url: URL?, placeholder: PlatformImage? = nil, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil) {
|
||||
self.init(url: url, placeholder: placeholder, options: options, context: context, isAnimating: .constant(true))
|
||||
}
|
||||
|
||||
public init(url: URL?, placeholder: PlatformImage? = nil, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil, isAnimating: Binding<Bool>) {
|
||||
self._isAnimating = isAnimating
|
||||
self.placeholder = placeholder
|
||||
self.webOptions = options
|
||||
self.webContext = context
|
||||
self.imageModel.url = url
|
||||
}
|
||||
|
||||
public init(name: String, bundle: Bundle? = nil) {
|
||||
self.init(name: name, bundle: bundle, isAnimating: .constant(true))
|
||||
}
|
||||
|
||||
public init(name: String, bundle: Bundle? = nil, isAnimating: Binding<Bool>) {
|
||||
self._isAnimating = isAnimating
|
||||
#if os(macOS)
|
||||
let image = SDAnimatedImage(named: name, in: bundle)
|
||||
#else
|
||||
let image = SDAnimatedImage(named: name, in: bundle, compatibleWith: nil)
|
||||
#endif
|
||||
self.imageModel.image = image
|
||||
}
|
||||
|
||||
public init(data: Data, scale: CGFloat = 0) {
|
||||
self.init(data: data, scale: scale, isAnimating: .constant(true))
|
||||
}
|
||||
|
||||
public init(data: Data, scale: CGFloat = 0, isAnimating: Binding<Bool>) {
|
||||
self._isAnimating = isAnimating
|
||||
let image = SDAnimatedImage(data: data, scale: scale)
|
||||
self.imageModel.image = image
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
public typealias NSViewType = AnimatedImageViewWrapper
|
||||
#else
|
||||
|
@ -90,6 +130,20 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
}
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
if self.isAnimating != view.wrapped.animates {
|
||||
view.wrapped.animates = self.isAnimating
|
||||
}
|
||||
#else
|
||||
if self.isAnimating != view.wrapped.isAnimating {
|
||||
if self.isAnimating {
|
||||
view.wrapped.startAnimating()
|
||||
} else {
|
||||
view.wrapped.stopAnimating()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
configureView(view, context: context)
|
||||
layoutView(view, context: context)
|
||||
}
|
||||
|
@ -310,30 +364,6 @@ extension AnimatedImage {
|
|||
}
|
||||
}
|
||||
|
||||
// Initializer
|
||||
extension AnimatedImage {
|
||||
public init(url: URL?, placeholder: PlatformImage? = nil, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil) {
|
||||
self.placeholder = placeholder
|
||||
self.webOptions = options
|
||||
self.webContext = context
|
||||
self.imageModel.url = url
|
||||
}
|
||||
|
||||
public init(name: String, bundle: Bundle? = nil) {
|
||||
#if os(macOS)
|
||||
let image = SDAnimatedImage(named: name, in: bundle)
|
||||
#else
|
||||
let image = SDAnimatedImage(named: name, in: bundle, compatibleWith: nil)
|
||||
#endif
|
||||
self.imageModel.image = image
|
||||
}
|
||||
|
||||
public init(data: Data, scale: CGFloat = 0) {
|
||||
let image = SDAnimatedImage(data: data, scale: scale)
|
||||
self.imageModel.image = image
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
struct AnimatedImage_Previews : PreviewProvider {
|
||||
static var previews: some View {
|
||||
|
|
Loading…
Reference in New Issue