Skip to content

Commit 3340ea4

Browse files
committed
Fix the compatibility with UIView transition
Actually this is not the good design, but at least a workaround
1 parent 1edee7f commit 3340ea4

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

SDWebImageSwiftUI/Classes/AnimatedImage.swift

+19-6
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,8 @@ public struct AnimatedImage : PlatformViewRepresentable {
275275
self.imageModel.placeholderView?.isHidden = false
276276
self.imageHandler.failureBlock?(error ?? NSError())
277277
}
278-
// Finished loading
279-
configureView(view, context: context)
280-
layoutView(view, context: context)
278+
// Finished loading, async
279+
finishUpdateView(view, context: context, image: image)
281280
}
282281
}
283282

@@ -310,6 +309,8 @@ public struct AnimatedImage : PlatformViewRepresentable {
310309
#endif
311310
context.coordinator.imageLoading.imageName = name
312311
view.wrapped.image = image
312+
// Finished loading, sync
313+
finishUpdateView(view, context: context, image: image)
313314
}
314315

315316
private func updateViewForData(_ data: Data?, view: AnimatedImageViewWrapper, context: Context) {
@@ -323,6 +324,8 @@ public struct AnimatedImage : PlatformViewRepresentable {
323324
}
324325
context.coordinator.imageLoading.imageData = data
325326
view.wrapped.image = image
327+
// Finished loading, sync
328+
finishUpdateView(view, context: context, image: image)
326329
}
327330

328331
private func updateViewForURL(_ url: URL?, view: AnimatedImageViewWrapper, context: Context) {
@@ -347,6 +350,8 @@ public struct AnimatedImage : PlatformViewRepresentable {
347350
setupIndicator(view, context: context)
348351
loadImage(view, context: context)
349352
}
353+
// Finished loading, sync
354+
finishUpdateView(view, context: context, image: view.wrapped.image)
350355
}
351356

352357
func updateView(_ view: AnimatedImageViewWrapper, context: Context) {
@@ -364,9 +369,6 @@ public struct AnimatedImage : PlatformViewRepresentable {
364369
break // impossible
365370
}
366371

367-
// Finished loading
368-
configureView(view, context: context)
369-
layoutView(view, context: context)
370372
if let viewUpdateBlock = imageHandler.viewUpdateBlock {
371373
viewUpdateBlock(view.wrapped, context)
372374
}
@@ -384,6 +386,17 @@ public struct AnimatedImage : PlatformViewRepresentable {
384386
}
385387
}
386388

389+
func finishUpdateView(_ view: AnimatedImageViewWrapper, context: Context, image: PlatformImage?) {
390+
// Finished loading
391+
if let imageSize = image?.size {
392+
view.imageSize = imageSize
393+
} else {
394+
view.imageSize = nil
395+
}
396+
configureView(view, context: context)
397+
layoutView(view, context: context)
398+
}
399+
387400
func layoutView(_ view: AnimatedImageViewWrapper, context: Context) {
388401
// AspectRatio && ContentMode
389402
#if os(macOS)

SDWebImageSwiftUI/Classes/ImageViewWrapper.swift

+14-6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class AnimatedImageViewWrapper : PlatformView {
2020
var interpolationQuality = CGInterpolationQuality.default
2121
var shouldAntialias = false
2222
var resizingMode: Image.ResizingMode?
23+
var imageSize: CGSize?
2324

2425
public override func draw(_ rect: CGRect) {
2526
#if os(macOS)
@@ -49,20 +50,27 @@ public class AnimatedImageViewWrapper : PlatformView {
4950

5051
public override var intrinsicContentSize: CGSize {
5152
/// Match the behavior of SwiftUI.Image, only when image is resizable, use the super implementation to calculate size
52-
let imageSize = wrapped.intrinsicContentSize
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+
}
5362
if let _ = resizingMode {
5463
/// Keep aspect ratio
55-
let noIntrinsicMetric = AnimatedImageViewWrapper.noIntrinsicMetric
56-
if (imageSize.width > 0 && imageSize.height > 0) {
57-
let ratio = imageSize.width / imageSize.height
64+
if contentSize.width > 0 && contentSize.height > 0 {
65+
let ratio = contentSize.width / contentSize.height
5866
let size = CGSize(width: ratio, height: 1)
5967
return size
6068
} else {
61-
return CGSize(width: noIntrinsicMetric, height: noIntrinsicMetric)
69+
return contentSize
6270
}
6371
} else {
6472
/// Not resizable, always use image size, like SwiftUI.Image
65-
return imageSize
73+
return contentSize
6674
}
6775
}
6876

0 commit comments

Comments
 (0)