Skip to content

SwiftUI.View image snapshot size doesn't use preference values #921

@CraigSiemens

Description

@CraigSiemens

Describe the bug

When taking an image snapshot of a SwiftUI View that uses a preference to affect it's size, the resulting image will:

  • be sized without the preference value
  • be drawn using the preference value

This causes the view to either:

  • be smaller than the image, so there's extra padding
  • be larger than the image, causing content of the view to be cut off

To Reproduce

Take a snapshot of this ExampleView as .image(layout: .sizeThatFits)

struct ExampleView: View {
    @State private var size: CGSize = .init(width: 20, height: 20)
    
    var body: some View {
        Color.red
            .preference(key: SizePreferenceKey.self, value: CGSize(width: 10, height: 10))
            .frame(width: size.width, height: size.height)
            .onPreferenceChange(SizePreferenceKey.self) { newSize in
                size = newSize
            }
            .border(.black)
    }
}

struct SizePreferenceKey: PreferenceKey {
    typealias Value = CGSize
    
    static var defaultValue: Value = .init(width: 30, height: 30)
    
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value
    }
}

Expected behavior
The image should be 10pt x 10pt matching the size of the red view with a black border.
should_example 1

Screenshots

The image is actually being created at 20pt x 20pt so there's extra space added around the view.
should_example 1

If the preference was set to a larger value (ie 50x50), the red view would be larger than the image causing the border to no longer be in the image.

Environment

  • swift-snapshot-testing version 1.17.5
  • Xcode 16.0
  • Swift 6.0
  • OS: iOS 18

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions