Add a circular image view with corner radius for an image in swiftUI
Asked Answered
S

2

16

How can I add a circular view similar to the attachment below. In the attachment, the check is the image icon and I want to add the green background color in circular shape. I have a solution in Swift but, couldn't implement the same in swiftUI.

Related posts to my question: Add a border with cornerRadius to an Image in SwiftUI Xcode beta 5. But, this doesn't solve my issue.

Swift code to this implemention:

var imageView = UIImageView()
override init(theme: Theme) {
    super.init(theme: theme)
    imageView.clipsToBounds = true
    setLayout()
  }

override func layoutSubviews() {
    super.layoutSubviews()
    let cornerRadius = frame.height / 2
    imageView.setCornerRadius(cornerRadius)
    setCornerRadius(cornerRadius)
  }

CheckImage

Sewell answered 14/12, 2021 at 18:18 Comment(0)
T
8

This is not the simplest thing to come up with. Use this struct as a separate view. It will return the image properly sized on the circle.

struct ImageOnCircle: View {
    
    let icon: String
    let radius: CGFloat
    let circleColor: Color
    let imageColor: Color // Remove this for an image in your assets folder.
    var squareSide: CGFloat {
        2.0.squareRoot() * radius
    }
    
    var body: some View {
        ZStack {
            Circle()
                .fill(circleColor)
                .frame(width: radius * 2, height: radius * 2)
            
            // Use this implementation for an SF Symbol
            Image(systemName: icon)
                .resizable()
                .aspectRatio(1.0, contentMode: .fit)
                .frame(width: squareSide, height: squareSide)
                .foregroundColor(imageColor)
            
            // Use this implementation for an image in your assets folder.
//            Image(icon)
//                .resizable()
//                .aspectRatio(1.0, contentMode: .fit)
//                .frame(width: squareSide, height: squareSide)
        }
    }
}
Tropology answered 14/12, 2021 at 19:34 Comment(2)
Thanks for the solution. This works perfectly.Sewell
Thank you for your answer @Tropology ! I used the resizable() property and now my images are correctly scaled to my parent ViewDichotomous
U
30

You could create this image like...

Image(systemName: "checkmark")
  .resizable()
  .frame(width: 20, height: 20)
  .foregroundColor(.white)
  .padding(20)
  .background(Color.green)
  .clipShape(Circle())

Or alternatively...

Image(systemName: "checkmark.circle.fill")
  .resizable()
  .frame(width: 40, height: 40) // put your sizes here
  .foregroundColor(.green)
Uncertainty answered 14/12, 2021 at 18:23 Comment(3)
Image doesn't have a modifier called backgroundColor, and for your second solution foregroundColor refers to the coloring the foreground elements. It had nothing to do with backgroundColor. None of your solutions works.Sewell
@Sewell I made a couple of changes. I had written it all in the browser on my phone. But as for "none of your solution works". The code was 80% there with a couple of tweaks that most beginners would be able to find for themselves. And the second one worked with the addition of the word Color after foreground.Uncertainty
The alternative solution is missing the bracket after resizable. Shoud be resizable()Laze
T
8

This is not the simplest thing to come up with. Use this struct as a separate view. It will return the image properly sized on the circle.

struct ImageOnCircle: View {
    
    let icon: String
    let radius: CGFloat
    let circleColor: Color
    let imageColor: Color // Remove this for an image in your assets folder.
    var squareSide: CGFloat {
        2.0.squareRoot() * radius
    }
    
    var body: some View {
        ZStack {
            Circle()
                .fill(circleColor)
                .frame(width: radius * 2, height: radius * 2)
            
            // Use this implementation for an SF Symbol
            Image(systemName: icon)
                .resizable()
                .aspectRatio(1.0, contentMode: .fit)
                .frame(width: squareSide, height: squareSide)
                .foregroundColor(imageColor)
            
            // Use this implementation for an image in your assets folder.
//            Image(icon)
//                .resizable()
//                .aspectRatio(1.0, contentMode: .fit)
//                .frame(width: squareSide, height: squareSide)
        }
    }
}
Tropology answered 14/12, 2021 at 19:34 Comment(2)
Thanks for the solution. This works perfectly.Sewell
Thank you for your answer @Tropology ! I used the resizable() property and now my images are correctly scaled to my parent ViewDichotomous

© 2022 - 2024 — McMap. All rights reserved.