Corner radius makes the image vanish

Viewed 373

I was experimenting with swiftUI and i found out that cornerRadius attributes makes my image disappear.

Image(uiImage: content.image)
    .resizable()
    .scaledToFill()
    .frame(width: 60, height: 40)
    .cornerRadius(3)

Is there something wrong with the code here ? I want my image to be resizable, fill the whole view, have a dimension of 60x40 and a cornerRadius of 3.

Thanks for your help, if you know what's wrong :)

XCode: 12.1 (12A7403)

3 Answers

I came across the same problem and I think it is either a bug, or a something new that came with Xcode 12.1, because it was working perfectly a few weeks back. I did try a lot of ways to put the .cornerRadius() but it always resulted in the Image vanishing. This is my final solution, but I do believe .cornerRadius() would be better here. I hope it will help you! The color of the stroke will need to be the color of your background.

Image("MyImage")
     .resizable()
     .frame(width: 19, height: 19, alignment: .center)
     .overlay(RoundedRectangle(cornerRadius: 4)
           .stroke(Color.white, lineWidth: 3.3)
     ) 

I have met similar problems. When I set the cornerRadius for a view on simulator, the view disappear. However, when running on the real device, the view shows up. I think it is a bug of Xcode, you may test on real device to see your view.

Here's how I worked around this.

I made an equivalent of ImageView with UIKit.

struct FixImageView: UIViewRepresentable {
    let image: UIImage
    let contentMode: UIView.ContentMode

    final class Coordinator: NSObject {}

    func makeCoordinator() -> Coordinator {
        Coordinator()
    }

    func makeUIView(context: Context) -> UIImageView {
        let view = UIImageView()
        view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        view.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
        view.image = image
        view.contentMode = contentMode
        return view
    }

    func updateUIView(_ uiView: UIImageView, context: Context) {
        uiView.image = image
        uiView.contentMode = contentMode
    }
}

You can use it just like a normal SwiftUI's Image.

@ViewBuilder
var body: some View {
    FixImageView(image: image, contentMode: .scaleAspectFit)
        .cornerRadius(20)
}

If you're wondering why the the compression priority is low, Tomas Linhart explains:

SwiftUI uses the compression resistance priority and the content hugging priority to decide what resizing is possible.

If you want to resize a view below its intrinsic content size, you need to reduce the compression resistance priority.
Related