admaDIC App Development & IT Solutions

SwiftUI Shapes

by Annett Schwarze | 2025-02-15

SwiftUI Shape

Shapes can be added to views by just creating them:.

Circles

GridRow {
    Circle()
        .fill(.yellow)
    Circle()
        .fill(.yellow)
        .border(.orange, width: 8)
    Circle()
        .stroke(.orange, lineWidth: 8)
    Circle()
        .stroke(.orange, lineWidth: 8)
        .background(Circle().fill(.yellow))

}.border(.green)
Some Cirlce Shapes

Rectangles

Unlike Circles, Rectangle have no restrictions on their dimensions. Rectangles are an example of Shapes, which fill their parent views.

The fourth Rectangle demonstates insets. First shapes can be inset from their parent's boundaries. In case of a RoundedRectangle, the corner radius of the inset shape is adjusted.

The overlay for the inset rectangle is not inset as the rectangle is. The overlay's boundaries correspond to the parent view's boundaries. Therefore, the translucent orange rectangle is larger than the yellow rounded rectangle.

GridRow {
    Rectangle()
        .fill(.yellow)
    RoundedRectangle(cornerSize: CGSize(width: 32, height: 16))
        .fill(.yellow)
    RoundedRectangle(cornerRadius: 32)
        .fill(.yellow)
    RoundedRectangle(cornerRadius: 32)
        .inset(by: 16)
        .fill(.yellow)
        .overlay(content: {
            Rectangle()
                .inset(by: 8)
                .fill(.orange.opacity(0.3))
        })
}.border(.green)
Rectangle shape samples

Ellipsis

An overlay is not automatically clipped by its parent view. It can be clipped by the parent view, but the clipped shape is then a Rectangle, not the original shape, which in this case would be an Ellipsis. Overlayed shapes can be inset, even by a negative value in which case they extend the parent shape's boundaries.

GridRow {
    Ellipse()
        .fill(.yellow)
    Ellipse()
        .fill(.yellow)
        .overlay(content: {
            Circle()
                .inset(by: -10)
                .fill(.orange)
        })
    Ellipse()
        .fill(.yellow)
        .overlay(content: {
            Circle()
                .inset(by: -10)
                .fill(.orange)
        })
        .clipped()
    Ellipse()
        .rotation(.radians(.pi / 16))
        .fill(.yellow)
        .overlay(content: {
            Circle()
                .inset(by: -10)
                .fill(.orange)
        })
}.border(.green)
Ellipsis examples

Custom Shapes

GridRow {
    Circle()
        .fill(.yellow)
    Star(n: 4, inner: 0.2)
        .fill(.yellow)
    Star(n: 8, inner: 0.4)
        .stroke(.red.opacity(0.5), style: StrokeStyle(lineWidth: 8.0, lineJoin: .round))
        .background(
            Star(n: 8, inner: 0.4)
                .fill(.yellow))
    Star(n: 16, inner: 0.7)
        .fill(.yellow)
}.border(.green)
    struct Star: Shape {
        var n: Int
        var inner: Double
        func path(in rect: CGRect) -> Path {
            let dim = min(rect.width, rect.height)
            let offset = CGPoint(x: rect.midX, y: rect.midY)
            let r = dim / 2.0
            var p = Path()
            for i in 0 ..< n {
                let a1 = (2.0 * Double(i) + 0) / (2.0 * Double(n))
                let a2 = (2.0 * Double(i) + 1) / (2.0 * Double(n))

                let x1 = r * cos(a1 * 2.0 * .pi)
                let y1 = r * sin(a1 * 2.0 * .pi)
                let x2 = r * inner * cos(a2 * 2.0 * .pi)
                let y2 = r * inner * sin(a2 * 2.0 * .pi)

                if i == 0 {
                    p.move(to: CGPoint(x: x1, y: y1))
                } else {
                    p.addLine(to: CGPoint(x: x1, y: y1))
                }
                p.addLine(to: CGPoint(x: x2, y: y2))
            }
            p.closeSubpath()
            p = p.applying(.init(translationX: offset.x, y: offset.y))
            return p
        }
    }
Custom Shape examples

 

www.admadic.de | webmaster@admadic.de | Legal Notice and Trademarks | Privacy
© 2005-2007 - admaDIC | All Rights Reserved
All other trademarks and/or registered trademarks are the property of their respective owners
Last Change: Sat Feb 15 10:04:32 2025 GMT