SwiftUI Image clipsToBounds

Viewed 23689

Experimenting with SwiftUI (Xcode 11.0 beta 2), I try to fill a View with an image :

Image("large")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(width: 80, height: 80, alignment: .center)
    .border(Color.black)

This renders like so :

No clipping

I would like to apply something similar to UIView.clipsToBounds so the image is clipped and the parts outside of the box are not visible.

4 Answers

You can use the .clipped() modifier, which results in an effect similar to UIView.clipsToBounds:

Image("large")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(width: 80, height: 80, alignment: .center)
    .border(Color.black)
    .clipped() // Equal to clipsToBounds = true
Image("large")
   .resizable()
   .clipShape(Circle())
   .frame(width: 200.0, height: 200.0)
   .overlay(Circle().stroke(Color.white,lineWidth:4).shadow(radius: 10))

OutPut

Image("large")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(width: 80, height: 80, alignment: .center)
+   .contentShape(Rectangle())
+   .clipped()
    .border(Color.black)

This helped me fixing the issue by image overlapping a button. contentShape() was used to clip hit-testing area. clipped() is clipping the contents inside the view's bounds(as others mentioned).

Use GeometryReader can fix the issue where if the clipped region of the image overlaps a button, that button will NOT work

like this:
GeometryReader { geo in
   Image("large")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(width: 80, height: 80, alignment: .center)
    .border(Color.black)
 }.frame(width: 150, height: hh)
Related