Search code examples
swiftui

Circular Image in SwiftUI Menu


Every time I put an Image as Menu content in SwiftUI, I am unable to round its edges or clip its shape. I'd like my displayed image to be the shape of a circle.

Of course, I've tried .cornerRadius() and .clipShape(Circle()). Minimal example:

Menu("Ben") {
  Toggle(isOn: .constant(true)) {
    Label {
      Text("Ben")
    } icon: {
      Image("blueGradient")
        .resizable()
        .clipShape(Circle())
    }
  }
}

Result of code example above


Solution

  • If you don't want to add round versions of the images to your asset catalog then you could always convert them to round images on the fly. The Image initializer that uses drawing instructions makes this possible:

    let roundImageSize: CGFloat = 72
    
    private func roundImage(name: String) -> Image {
        let size = CGSize(width: roundImageSize, height: roundImageSize)
        return Image(size: size) { ctx in
            let sourceImage = Image(name)
            let resolvedImage = ctx.resolve(sourceImage)
            ctx.clip(to: Path(ellipseIn: CGRect(origin: .zero, size: size)))
            ctx.draw(resolvedImage, in: CGRect(origin: .zero, size: size))
        }
    }
    
    var body: some View {
        Menu("Ben") {
            Toggle(isOn: .constant(true)) {
                Label {
                    Text("Ben")
                } icon: {
                    roundImage(name: "blueGradient")
                }
            }
        }
    }
    

    Screenshot