0

I'm working on creating a "bridge" shape in SwiftUI by combining a rectangle and a circle. I believe using a method like .union might be the solution, but I'm having trouble figuring out how to implement it correctly. My goal is to merge a rectangle and a circle to create a shape that resembles a bridge. Specifically, I want the top side of the rectangle to have an inset curve. Additionally, I'd like to place an image in the background of this composite shape. Essentially, the final design should be a rectangle with a curved inset at the top and an image set behind it.

Some help woud be great! thanks

ZStack {
        Rectangle()
            .fill(.blue)
            .frame(height:250)

       Image("BGImage")
        
        Circle()
            .fill(.white)
            .frame(width: 700)
            .offset(y:-400)
    }

Thats the goal:

Screenshot

1 Answer 1

2

One way to build the shape is to start with the path of a rectangle and then use subtracting(_:eoFill:) to subtract the path of a circle (requires iOS 17).

  • The diameter of the circle can be made dependent on the width of the shape.
  • The center-point for the circle can then be calculated using Pythagoras.
struct BridgeShape: Shape {
    func path(in rect: CGRect) -> Path {
        let w = rect.width
        let factor = 1.8 // smaller factor = deeper bite
        let diameter = w * factor
        let yOffset = sqrt((diameter * diameter) - (w * w)) / 2
        let circlePath = Path { path in
            path.addEllipse(in: CGRect(
                x: rect.midX - (diameter / 2),
                y: rect.minY - (diameter / 2) - yOffset,
                width: diameter,
                height: diameter
            ))
        }
        return Path(rect).subtracting(circlePath)
    }
}

Examples of use:

  • Fill with solid color
BridgeShape()
    .fill(.blue)
    .frame(height: 250)

Screenshot

  • Use as a clip shape
Image("BGImage")
    .resizable()
    .scaledToFill()
    .frame(height: 250)
    .clipShape(BridgeShape())

Screenshot

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.