Skip to content

Commit

Permalink
Fix the transition visual jump between placeholderImage and final ima…
Browse files Browse the repository at this point in the history
…ge for AnimatedImage
  • Loading branch information
dreampiggy committed Jul 1, 2024
1 parent 26f7571 commit d7c7639
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 19 deletions.
11 changes: 3 additions & 8 deletions SDWebImageSwiftUI/Classes/AnimatedImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
self.imageHandler.failureBlock?(error ?? NSError())
}
// Finished loading, async
finishUpdateView(view, context: context, image: image)
finishUpdateView(view, context: context)
}
}

Expand Down Expand Up @@ -364,7 +364,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
}

// Finished loading, sync
finishUpdateView(view, context: context, image: view.wrapped.image)
finishUpdateView(view, context: context)

if let viewUpdateBlock = imageHandler.viewUpdateBlock {
viewUpdateBlock(view.wrapped, context)
Expand All @@ -383,13 +383,8 @@ public struct AnimatedImage : PlatformViewRepresentable {
}
}

func finishUpdateView(_ view: AnimatedImageViewWrapper, context: Context, image: PlatformImage?) {
func finishUpdateView(_ view: AnimatedImageViewWrapper, context: Context) {
// Finished loading
if let imageSize = image?.size {
view.imageSize = imageSize
} else {
view.imageSize = nil
}
configureView(view, context: context)
layoutView(view, context: context)
}
Expand Down
24 changes: 13 additions & 11 deletions SDWebImageSwiftUI/Classes/ImageViewWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ import SwiftUI
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
public class AnimatedImageViewWrapper : PlatformView {
/// The wrapped actual image view, using SDWebImage's aniamted image view
public var wrapped = SDAnimatedImageView()
@objc dynamic public var wrapped = SDAnimatedImageView()
var observation: NSKeyValueObservation?
var interpolationQuality = CGInterpolationQuality.default
var shouldAntialias = false
var resizingMode: Image.ResizingMode?
var imageSize: CGSize?

deinit {
observation?.invalidate()
}

public override func draw(_ rect: CGRect) {
#if os(macOS)
Expand Down Expand Up @@ -50,15 +54,7 @@ public class AnimatedImageViewWrapper : PlatformView {

public override var intrinsicContentSize: CGSize {
/// Match the behavior of SwiftUI.Image, only when image is resizable, use the super implementation to calculate size
var contentSize = wrapped.intrinsicContentSize
/// Sometimes, like during the transaction, the wrapped.image == nil, which cause contentSize invalid
/// Use image size as backup
/// TODO: This mixed use of UIKit/SwiftUI animation will cause visial issue because the intrinsicContentSize during animation may be changed
if let imageSize = imageSize {
if contentSize != imageSize {
contentSize = imageSize
}
}
let contentSize = wrapped.intrinsicContentSize
if let _ = resizingMode {
/// Keep aspect ratio
if contentSize.width > 0 && contentSize.height > 0 {
Expand All @@ -77,11 +73,17 @@ public class AnimatedImageViewWrapper : PlatformView {
public override init(frame frameRect: CGRect) {
super.init(frame: frameRect)
addSubview(wrapped)
observation = observe(\.wrapped.image, options: [.new]) { observe, change in
self.invalidateIntrinsicContentSize()
}
}

public required init?(coder: NSCoder) {
super.init(coder: coder)
addSubview(wrapped)
observation = observe(\.wrapped.image, options: [.new]) { observe, change in
self.invalidateIntrinsicContentSize()
}
}
}

Expand Down

0 comments on commit d7c7639

Please sign in to comment.