Skip to content

Commit bd635fd

Browse files
committed
Implements the AnimatedImage's aspectRatio method, which match the SwiftUI.Image behavior.
Using some trick code, but it works at least
1 parent a2f0b2d commit bd635fd

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

SDWebImageSwiftUI/Classes/AnimatedImage.swift

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,11 @@ public struct AnimatedImage : PlatformViewRepresentable {
269269

270270
func layoutView(_ view: AnimatedImageViewWrapper, context: PlatformViewRepresentableContext<AnimatedImage>) {
271271
// AspectRatio
272-
if let _ = imageLayout.aspectRatio {
273-
// TODO: Needs layer transform and geometry calculation
274-
}
272+
// If `aspectRatio` is `nil`, the resulting view maintains this view's aspect ratio.
273+
let contentMode: ContentMode = imageLayout.aspectRatio == nil ? .fit : .fill
275274

276275
// ContentMode
277-
switch imageLayout.contentMode {
276+
switch contentMode {
278277
case .fit:
279278
#if os(macOS)
280279
view.wrapped.imageScaling = .scaleProportionallyUpOrDown
@@ -471,10 +470,18 @@ extension AnimatedImage {
471470
/// fill the parent context.
472471
/// - Returns: A view that constrains this view's dimensions to
473472
/// `aspectRatio`, using `contentMode` as its scaling algorithm.
474-
public func aspectRatio(_ aspectRatio: CGFloat? = nil, contentMode: ContentMode) -> AnimatedImage {
473+
public func aspectRatio(_ aspectRatio: CGFloat? = nil, contentMode: ContentMode) -> some View {
474+
// The `SwifUI.View.aspectRatio(_:contentMode:)` says:
475+
// If `aspectRatio` is `nil`, the resulting view maintains this view's aspect ratio
476+
// But 1: there are no public API to declare what `this view's aspect ratio` is
477+
// So, if we don't override this method, SwiftUI ignore the content mode on actual ImageView
478+
// To workaround, we want to call the default `SwifUI.View.aspectRatio(_:contentMode:)` method
479+
// But 2: there are no way to call a Protocol Extention default implementation in Swift 5.1
480+
// So, we need a hack, that create a empty modifier, they call method on that view instead
481+
// Fired Radar: FB7413534
475482
imageLayout.aspectRatio = aspectRatio
476483
imageLayout.contentMode = contentMode
477-
return self
484+
return self.modifier(EmptyModifier()).aspectRatio(aspectRatio, contentMode: contentMode)
478485
}
479486

480487
/// Constrains this view's dimensions to the aspect ratio of the given size.
@@ -485,7 +492,7 @@ extension AnimatedImage {
485492
/// fill the parent context.
486493
/// - Returns: A view that constrains this view's dimensions to
487494
/// `aspectRatio`, using `contentMode` as its scaling algorithm.
488-
public func aspectRatio(_ aspectRatio: CGSize, contentMode: ContentMode) -> AnimatedImage {
495+
public func aspectRatio(_ aspectRatio: CGSize, contentMode: ContentMode) -> some View {
489496
var ratio: CGFloat?
490497
if aspectRatio.width > 0 && aspectRatio.height > 0 {
491498
ratio = aspectRatio.width / aspectRatio.height
@@ -496,15 +503,15 @@ extension AnimatedImage {
496503
/// Scales this view to fit its parent.
497504
/// - Returns: A view that scales this view to fit its parent,
498505
/// maintaining this view's aspect ratio.
499-
public func scaledToFit() -> AnimatedImage {
500-
self.aspectRatio(nil, contentMode: .fit)
506+
public func scaledToFit() -> some View {
507+
return self.aspectRatio(nil, contentMode: .fit)
501508
}
502509

503510
/// Scales this view to fill its parent.
504511
/// - Returns: A view that scales this view to fit its parent,
505512
/// maintaining this view's aspect ratio.
506-
public func scaledToFill() -> AnimatedImage {
507-
self.aspectRatio(nil, contentMode: .fill)
513+
public func scaledToFill() -> some View {
514+
return self.aspectRatio(nil, contentMode: .fill)
508515
}
509516
}
510517

0 commit comments

Comments
 (0)