Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fc52658

Browse files
Merge pull request #326 from SDWebImage/bugfix/transition_animatedImage
Fix the transition visual jump between placeholderImage and final image for AnimatedImage
2 parents 02b2579 + d68c13a commit fc52658

File tree

4 files changed

+32
-34
lines changed

4 files changed

+32
-34
lines changed

‎SDWebImageSwiftUI/Classes/AnimatedImage.swift‎

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
276276
self.imageHandler.failureBlock?(error ?? NSError())
277277
}
278278
// Finished loading, async
279-
finishUpdateView(view, context: context, image: image)
279+
finishUpdateView(view, context: context)
280280
}
281281
}
282282

@@ -364,7 +364,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
364364
}
365365

366366
// Finished loading, sync
367-
finishUpdateView(view, context: context, image: view.wrapped.image)
367+
finishUpdateView(view, context: context)
368368

369369
if let viewUpdateBlock = imageHandler.viewUpdateBlock {
370370
viewUpdateBlock(view.wrapped, context)
@@ -383,13 +383,8 @@ public struct AnimatedImage : PlatformViewRepresentable {
383383
}
384384
}
385385

386-
func finishUpdateView(_ view: AnimatedImageViewWrapper, context: Context, image:PlatformImage?) {
386+
func finishUpdateView(_ view: AnimatedImageViewWrapper, context: Context) {
387387
// Finished loading
388-
if let imageSize = image?.size {
389-
view.imageSize = imageSize
390-
} else {
391-
view.imageSize = nil
392-
}
393388
configureView(view, context: context)
394389
layoutView(view, context: context)
395390
}

‎SDWebImageSwiftUI/Classes/ImageManager.swift‎

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public final class ImageManager : ObservableObject {
6060
weak var currentOperation: SDWebImageOperation? = nil
6161

6262
var currentURL: URL?
63+
var transaction = Transaction()
6364
var successBlock: ((PlatformImage, Data?, SDImageCacheType) -> Void)?
6465
var failureBlock: ((Error) -> Void)?
6566
var progressBlock: ((Int, Int) -> Void)?
@@ -106,18 +107,20 @@ public final class ImageManager : ObservableObject {
106107
// So previous View struct call `onDisappear` and cancel the currentOperation
107108
return
108109
}
109-
self.image = image
110-
self.error = error
111-
self.isIncremental = !finished
112-
if finished {
113-
self.imageData = data
114-
self.cacheType = cacheType
115-
self.indicatorStatus.isLoading = false
116-
self.indicatorStatus.progress = 1
117-
if let image = image {
118-
self.successBlock?(image, data, cacheType)
119-
} else {
120-
self.failureBlock?(error ?? NSError())
110+
withTransaction(transaction) {
111+
self.image = image
112+
self.error = error
113+
self.isIncremental = !finished
114+
if finished {
115+
self.imageData = data
116+
self.cacheType = cacheType
117+
self.indicatorStatus.isLoading = false
118+
self.indicatorStatus.progress = 1
119+
if let image = image {
120+
self.successBlock?(image, data, cacheType)
121+
} else {
122+
self.failureBlock?(error ?? NSError())
123+
}
121124
}
122125
}
123126
}

‎SDWebImageSwiftUI/Classes/ImageViewWrapper.swift‎

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@ import SwiftUI
1616
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
1717
public class AnimatedImageViewWrapper : PlatformView {
1818
/// The wrapped actual image view, using SDWebImage's aniamted image view
19-
public var wrapped = SDAnimatedImageView()
19+
@objc dynamic public var wrapped = SDAnimatedImageView()
20+
var observation: NSKeyValueObservation?
2021
var interpolationQuality = CGInterpolationQuality.default
2122
var shouldAntialias = false
2223
var resizingMode: Image.ResizingMode?
23-
var imageSize: CGSize?
24+
25+
deinit {
26+
observation?.invalidate()
27+
}
2428

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

5155
public override var intrinsicContentSize: CGSize {
5256
/// Match the behavior of SwiftUI.Image, only when image is resizable, use the super implementation to calculate size
53-
var contentSize = wrapped.intrinsicContentSize
54-
/// Sometimes, like during the transaction, the wrapped.image == nil, which cause contentSize invalid
55-
/// Use image size as backup
56-
/// TODO: This mixed use of UIKit/SwiftUI animation will cause visial issue because the intrinsicContentSize during animation may be changed
57-
if let imageSize = imageSize {
58-
if contentSize != imageSize {
59-
contentSize = imageSize
60-
}
61-
}
57+
let contentSize = wrapped.intrinsicContentSize
6258
if let _ = resizingMode {
6359
/// Keep aspect ratio
6460
if contentSize.width > 0 && contentSize.height > 0 {
@@ -77,11 +73,17 @@ public class AnimatedImageViewWrapper : PlatformView {
7773
public override init(frame frameRect: CGRect) {
7874
super.init(frame: frameRect)
7975
addSubview(wrapped)
76+
observation = observe(\.wrapped.image, options: [.new]) { _, _ in
77+
self.invalidateIntrinsicContentSize()
78+
}
8079
}
8180

8281
public required init?(coder: NSCoder) {
8382
super.init(coder: coder)
8483
addSubview(wrapped)
84+
observation = observe(\.wrapped.image, options: [.new]) { _, _ in
85+
self.invalidateIntrinsicContentSize()
86+
}
8587
}
8688
}
8789

‎SDWebImageSwiftUI/Classes/WebImage.swift‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ final class WebImageConfiguration: ObservableObject {
8181
/// A Image View type to load image from url. Supports static/animated image format.
8282
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
8383
public struct WebImage<Content> : View where Content: View {
84-
var transaction: Transaction
85-
8684
var configurations: [(Image) -> Image] = []
8785

8886
var content: (WebImagePhase) -> Content
@@ -146,10 +144,10 @@ public struct WebImage<Content> : View where Content: View {
146144
imageModel.context = context
147145
_imageModel = ObservedObject(wrappedValue: imageModel)
148146
let imageManager = ImageManager()
147+
imageManager.transaction = transaction
149148
_imageManager = StateObject(wrappedValue: imageManager)
150149
_indicatorStatus = ObservedObject(wrappedValue: imageManager.indicatorStatus)
151150

152-
self.transaction = transaction
153151
self.content = { phase in
154152
content(phase)
155153
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /