1

I want to display a paging view of images sized to a certain aspect ratio. This is straightforward enough with a single image, but using a TabView seems to have some strange sizing behavior. I can't get it to size correctly within the stack that it is in.

The image shows an example of a single image. It should still look like this with the ability to page.

enter image description here

VStack(spacing: 15.0) {
    if viewModel.images.count == 1 {
        WebImage(url: viewModel.images.first)
            .fitToAspectRatio(.sixteenToNine)
            .cornerRadius(4)
    } else {
        // TODO: Figure out sizing issues
        TabView {
            ForEach(viewModel.images) { image in
                WebImage(url: image)
                    .fitToAspectRatio(.sixteenToNine)
            }
        }
        .tabViewStyle(PageTabViewStyle())
        .aspectRatio(1.77, contentMode: .fit)
        .cornerRadius(4)
    }
}

The whole structure collapses and the image is tiny enter image description here

Here is the fitToAspectRatio modifier used on the image itself code for completeness

/// Fit an image to a certain aspect ratio while maintaining its aspect ratio
public struct FitToAspectRatio: ViewModifier {
    
    private let aspectRatio: CGFloat
    
    public init(_ aspectRatio: CGFloat) {
        self.aspectRatio = aspectRatio
    }
    
    public init(_ aspectRatio: AspectRatio) {
        self.aspectRatio = aspectRatio.rawValue
    }
    
    public func body(content: Content) -> some View {
        ZStack {
            Rectangle()
                .fill(Color(.clear))
                .aspectRatio(aspectRatio, contentMode: .fit)

            content
                .scaledToFill()
                .layoutPriority(-1)
        }
        .clipped()
    }
}

public extension WebImage {
    func fitToAspectRatio(_ aspectRatio: CGFloat) -> some View {
        self.resizable().modifier(FitToAspectRatio(aspectRatio))
    }
    
    func fitToAspectRatio(_ aspectRatio: AspectRatio) -> some View {
        self.resizable().modifier(FitToAspectRatio(aspectRatio))
    }
}
Chris
  • 1,750
  • 2
  • 14
  • 23

1 Answers1

0

Do it for content not for TabView itself, like

    TabView {
        ForEach(viewModel.images) { image in
            WebImage(url: image)
                .fitToAspectRatio(.sixteenToNine)
        }
        .aspectRatio(1.77, contentMode: .fit)      // << here !!
        .cornerRadius(4)
    }
    .tabViewStyle(PageTabViewStyle())
Asperi
  • 228,894
  • 20
  • 464
  • 690