deanWombourne
deanWombourne

Reputation: 38485

Draw a circle around Text in SwiftUI

This should be simple - so simple I'm pretty sure I've missed something obvious!

I want to have some text with a circle drawn round it. The tricky part is making the frame of the view be that of the circle, not the frame of the text.

Here is what I have at the moment:

struct CircledText: View {

    let text: String

    var body: some View {
        Text(text)
            .padding()
            .background(Circle()
                            .strokeBorder()
                            .aspectRatio(1, contentMode: .fill))
            .border(.orange)
    }
}

but this doesn't make the frame of the view match the circle - the frame is the frame of the text+padding.

Here are three previews with different length text.

Three previews of the circled text

How can I create a view so that the bounds of the view equal that of the circle, not the text?

Upvotes: 3

Views: 5053

Answers (4)

muhammad tayyab
muhammad tayyab

Reputation: 11

ZStack {
    Circle()
        .foregroundColor(.orange)
        .frame(width: 30, height: 30)
    Text("+2")
        .foregroundColor(.white)
        .frame(width: 22.0, height: 13.0, alignment: .center)
        .font(.custom("HelveticaNeue-Medium", size: 11.0))
}

also this is a small and perfect demo for draw a circle and adjust the text on it in swiftUi , i hope i will help you , thank you

Upvotes: 0

Giuseppe Mazzilli
Giuseppe Mazzilli

Reputation: 502

You can use a custom shape:

struct Circle: Shape {
    func path(in rect: CGRect) -> Path {
        let radius = sqrt(rect.midX * rect.midX + rect.midY * rect.midY)
        let center = CGPoint(x: rect.midX, y: rect.midY)

        var path = Path()
        path.move(to: center)
        path.addArc(center: center, radius: radius, startAngle: .zero, endAngle: .degrees(360), clockwise: false)

        return path
    }
}

and then use in your own view:

struct CircleButton: View {
    var body: some View {
        Text("Demo")
            .foregroundColor(.white)
            .background(
                Circle()
            )
    }
}

Upvotes: 0

Emilia Larssen
Emilia Larssen

Reputation: 105

I am not sure, but is it what you are looking for?

VStack(spacing: 50) {
    CircleInRectangleTextView(width: 100, height: 50, text: "1")
    CircleInRectangleTextView(width: 50, height: 50, text: "1")
    CircleInRectangleTextView(width: 30, height: 70, text: "1")
}


struct CircleInRectangleTextView: View {
    let width: Double
    let height: Double
    let text: String
    var body: some View {
        Text(text)
            .background(
                Rectangle()
                    .strokeBorder()
                    .border(.orange)
                    .frame(width: width, height: height)
            )
            .overlay(
                Ellipse()
                    .strokeBorder()
                    .frame(width: width, height: height)
            )
    }
}

enter image description here

Upvotes: 1

swiftPunk
swiftPunk

Reputation: 1

You can look at this way:

struct ContentView: View {
    
    var body: some View {
        
        CircledText(text: "Hello, world!")
            .border(Color.orange)
        
    }
    
}

struct CircledText: View {

    let text: String
    @State private var radius: CGFloat = .zero

    var body: some View {
        
        return ZStack {
            
            Text(text)
                .padding()
                .background(GeometryReader { proxy in Color.clear.onAppear() { radius = max(proxy.size.width, proxy.size.height) } }.hidden())
            
            if (!radius.isZero) {
                
                Circle().strokeBorder().frame(width: radius, height: radius)
                
            }
            
        }
     
    }
}

enter image description here

Upvotes: 5

Related Questions