# SwiftUI Shapes

Hi all, today I’d like to share a summary of standard shapes in SwiftUI. If you’re interested in custom shapes as well, leave a comment below and I’ll do another post.

The code of this post is available [here](https://github.com/xavier7t/iOSDevX/tree/main/iOSDevX/202303-Mar%202023/Standard%20Shapes%20in%20SwiftUI).

# Overview

`Shape` is a public protocol in SwiftUI since iOS 13 and the `Shape` protocol itself conform to another two protocol: `Animatable` and (SwiftUI) `View`.

SwiftUI provides us with several standard view structures that conform to the `Shape` protocol, and let’s take a look at what they are and how to style them with view modifiers.

# Shape View Structures

Except for `Path` structure which is often used for creating custom shapes, there’s are five shape views, and they can be grouped into two categories:

* Rectangular shapes: Rectangle, Rounded Rectangle.
    
* Circular shapes: Circle, Ellipse, Capsule.
    

We can initialize these shapes without any parameter, and control the size of such shapes with the view modifier `frame`. The only exception is the Rounded rectangle, the initializer of which has a parameter of `cornerRadius`.

Note that the`Capsule` and `Rounded Rectangle` structures are different from each other. A rounded rectangle is a variant of the rectangle, with a corner radius and it is a rectangular shape. On the contrary, a capsule is a circular shape, like an outline of the dynamic island of an iPhone 14 Pro.

```swift
VStack {
    
    //MARK: Rectangular shapes
    HStack {
        Text("Rectangle" + ":").bold()
        Spacer()
        Rectangle()
            .frame(width: 150, height: 50)
    }
    HStack {
        Text("Rounded Rectangle" + ":").bold()
        Spacer()
        RoundedRectangle(cornerRadius: 15)
            .frame(width: 150, height: 50)
    }
    //MARK: Circular shapes
    HStack {
        Text("Circle" + ":").bold()
        Spacer()
        Circle()
            .frame(width: 50, height: 50)
    }
    HStack {
        Text("Ellipse" + ":").bold()
        Spacer()
        Ellipse()
            .frame(width: 150, height: 50)
    }
    HStack {
        Text("Capsule" + ":").bold()
        Spacer()
        Capsule()
            .frame(width: 150, height: 50)
    }
    HStack {
        Text("Shape Modifiers")
            .font(.title3)
            .bold()
        Spacer()
    }
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678162744156/4ecab99e-846c-43f2-b88d-0202d7a62b59.png align="center")

# View modifiers for the shapes

## Frame

As demonstrated above, the `frame` modifier can be used to control the size of a shape since it’s putting a shape inside an invisible rectangular view.

For instance, in the following code snippet, there are two circle shapes declared. Circle1 and Circle2 will look exactly the same, with a radius of 50. However, since circle2 is put inside a wider frame, the space it takes will be wider.

```swift
let circle1 = Circle().frame(width: 50, height: 50)
let circle2 = Circle().frame(width: 150, height: 50)
```

## Stroke

The `stroke` view modifier adds an outline/ a borderline for the view it modifies. We can also make it dashed with a `StrokeStyle` as a parameter. The stroke style has a line width and a dash that are both customizable.

```swift
HStack {
    Text("Unmodified Stroke").bold()
    Spacer()
    Capsule()
        .stroke()
        .frame(width: 120, height: 40)
}
HStack {
    Text("Stroke with style").bold()
    Spacer()
    Capsule()
        .stroke(style: StrokeStyle(lineWidth: 2, dash: [5]))
        .frame(width: 120, height: 40)
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678163339974/16cfb1f9-fa78-476f-862c-c6faa021f957.png align="center")

## Foreground Color & Overlay

The modifier `foregroundColor` sets the foreground color of the shape it modifies, as its name suggests, the parameter we need is a SwiftUI color.

We covered the `stroke` modifier in the section above. But what if we need a shape with a foreground color and a border? In this case, we can add an `overlay` with the same shape inside, with a stroke modifier.

```swift
HStack {
    Text("Fg Color + Stroke overlay").bold()
    Spacer()
    Capsule()
        .frame(width: 120, height: 40)
        .foregroundColor(.accentColor)
        .overlay {
            Capsule().stroke(lineWidth: 2)
        }
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678163693287/b8ef8bbf-e638-45df-89f7-1a6d4da81991.png align="center")

## Fill

Sometimes, we need to have gradient color in our shape and `foregroundColor` won’t be able to do that since it requires a SwiftUI color. In this case, we can use a `fill` modifier instead of `foregroundColor`, so that the fill contents can be further customized.

For instance, the following code snippet has a Capsule modified by `fill`. Inside the full modifier, a `LinearGradient` is defined, with two colors - indigo and red, the gradient direction is from top leading (left) to bottom trailing (right).

```swift
HStack {
    Text("Filled with color gradient").bold()
    Spacer()
    Capsule()
        .fill(LinearGradient(colors: [.indigo, .red], startPoint: .topLeading, endPoint: .bottomTrailing))
        .frame(width: 120, height: 40)
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1678164110285/c59596c9-f338-4b9b-acb3-5d968ebf7c23.png align="center")

Well, that’s all for this summary of standard SwiftUI shapes. If you find it useful, don’t forget to hit the like button and subscribe to my newsletter. I’ll see you in the next post.\\
