Chapters

Hide chapters

SwiftUI Cookbook

Live Edition · iOS 16.4 · Swift 5.8.1 · Xcode 14.3.1

Create a Custom Shape for an Image in SwiftUI
Written by Team Kodeco

SwiftUI provides various ways to customize and add flair to images in your app. In addition to resizing, scaling and cropping images, you can also create a custom shape for an image using SwiftUI’s Path and Shape structs.

First, you need to create a custom shape that fits the desired shape of your image. You can achieve this by using SwiftUI’s Path struct, which allows you to specify a series of points and lines to create a shape. Then, you can use this custom shape to mask your image and create the desired effect.

For example, let’s say you want to create a circular image in your app. You can do this by creating a custom shape using the Path struct, like so:

struct StarShape: Shape {
  let points: Int
  let smoothness: CGFloat

  func path(in rect: CGRect) -> Path {
    assert(points >= 2, "A star must have at least 2 points")

    let center = CGPoint(x: rect.width / 2, y: rect.height / 2)
    let outerRadius = min(rect.width, rect.height) / 2
    let innerRadius = outerRadius * smoothness

    let path = Path { path in
      let angleIncrement = .pi * 2 / CGFloat(points)
      let rotationOffset = CGFloat.pi / 2

      for point in 0..<points {
        let angle = angleIncrement * CGFloat(point) - rotationOffset
        let tippedAngle = angle + angleIncrement / 2

        let outerPoint = CGPoint(x: center.x + cos(angle) * outerRadius, y: center.y + sin(angle) * outerRadius)
        let innerPoint = CGPoint(x: center.x + cos(tippedAngle) * innerRadius, y: center.y + sin(tippedAngle) * innerRadius)

        if point == 0 {
          path.move(to: outerPoint)
        } else {
          path.addLine(to: outerPoint)
        }

        path.addLine(to: innerPoint)
      }

      path.closeSubpath()
    }
    return path
  }
}

In the above code example, we define a StarShape struct that conforms to the Shape protocol. This custom shape takes a CGRect parameter and returns a Path struct that describes the circular shape. We achieve this by using the path(in:) method of the Shape protocol, which creates a Path struct and adds the appropriate points and lines to describe the desired shape.

You can use this custom shape to mask your image and create an effect like so:

struct ContentView: View {
  var body: some View {
    Image("TwoCapybaras")
      .resizable()
      .aspectRatio(contentMode: .fit)
      .clipShape(StarShape(points: 5, smoothness: 0.4))
  }
}

Note: If you want to try out the examples, you can download an archive of all the images used in this section here.

The preview should look as follows:

Create a new Shape with Path, then use it as an image mask.
Create a new Shape with Path, then use it as an image mask.

In the above code example, we load the image using the Image struct and set it to be resizable and aspect ratio-fitting. Then, we add the clipShape modifier to mask the image using our custom StarShape. This creates a star-like image effect.

As you can see, you can use SwiftUI’s Path and Shape structs to create custom shapes for your images and add a unique visual flair to your app. You can also experiment with different shapes and effects by creating and applying your custom shapes.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.