Erstellen komplexer SwiftUI-Formen mit Designtools

Feb 04 2023
Eine einfache Möglichkeit, Design in Code umzuwandeln. SwiftUI bietet uns 5 integrierte Formen zur Verwendung in unseren Projekten. Dies sind „Rechteck“, „RoundedRectangle“ (mit einem Eckradiusparameter), „Kapsel“, „Ellipse“ und „Kreis“.

Eine einfache Möglichkeit, Design in Code umzuwandeln

Quelle: Christina Kirschnerova

SwiftUI bietet uns 5 integrierte Formen zur Verwendung in unseren Projekten.

Dies sind Rectangle, RoundedRectangle(mit einem Eckenradiusparameter), Capsule, Ellipseund Circle.

Sehen wir es uns in Aktion an:

struct ShapesView: View {
    var body: some View {
        VStack (spacing: 10) {
            Rectangle()
                .fill(.pink)
                .frame(width: 100, height: 50)

            RoundedRectangle(cornerRadius: 10, style: .continuous)
                .fill(.purple)
                .frame(width: 100, height: 100)

            Capsule()
                .fill(.blue)
                .frame(width: 150, height: 150)

            Ellipse()
                .fill(.red)
                .frame(width: 150, height: 100)

            Circle()
                .fill(.green)
                .frame(width: 150, height: 250)
        }
    }
}

Xcode-Version 14.2

Shapesund Pathssind leistungsstarke Grundelemente, die in vielen Situationen verwendet werden können.

Es gibt jedoch Fälle, in denen komplexere Formen erforderlich sind. Apple bietet Unterstützung für benutzerdefiniertes Zeichnen mit zwei integrierten Tools: Pathsund Shapes.

Eine Form besteht aus einer Reihe von Pfaden. Paul Hudson hat eine großartige Einführung in diese Tools.

Schauen wir uns an, wie es in Aktion aussieht, und zeichnen wir mithilfe des ShapeProtokolls ein einfaches Sechseck.

struct Hexagon: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        let width = rect.width
        let height = rect.height
        let x = rect.midX
        let y = rect.midY
        let side = min(width, height) / 2.0
        let a = side / 2.0
        let b = side * sqrt(3.0) / 2.0
        path.move(to: CGPoint(x: x, y: y - side))
        path.addLine(to: CGPoint(x: x + a, y: y - b))
        path.addLine(to: CGPoint(x: x + a, y: y + b))
        path.addLine(to: CGPoint(x: x, y: y + side))
        path.addLine(to: CGPoint(x: x - a, y: y + b))
        path.addLine(to: CGPoint(x: x - a, y: y - b))
        path.closeSubpath()
        return path
    }
}

      
                
Hexagon created using SwiftUI’s shape method.

Lassen Sie uns als Beispiel ein neomorphes Widget für unsere App zur Gewohnheitsverfolgung erstellen:

Screenshot eines gewünschten Ergebnisses

Um einen Tiefeneffekt für die Zahl 12 zu erzielen, Text(“12”)reicht es nicht aus, einfach normale Modifikatoren zu verwenden und innere Schattenmodifikatoren anzuwenden. Wir müssen es mit erstellen Shapes.

Um dies zu erreichen, verwenden wir zum Erstellen der Formen ein Vektorgrafik-Tool wie Figma (kostenlos) oder Sketch (kostenpflichtig).

Platzieren Sie zunächst einen Screenshot eines Objekts, das Sie als Form replizieren möchten, im Hintergrund.

2. Beginnen Sie dann oben im Screenshot mit dem Zeichnen von Zahlen mithilfe von Kurven (Hotkey „V“ in Sketch).

3. Exportieren Sie Ihre erstellte Form im SVG-Format.

4. Öffnen Sie die gespeicherte Datei mit TextEditorund kopieren Sie den Code

Dieser Code ist im Grunde unsere SVG-Zeichnung.

5. Dann öffnenhttps://svg-to-swiftui.quassum.com/, (Es ist kostenlos, aber erwägen Sie eine Spende als Ausdruck Ihrer Dankbarkeit), fügen Sie unseren Code in den linken Block ein und klicken Sie auf „Konvertieren“. Sie können das Ergebnis endlich kopieren.

Quelle: https://svg-to-swiftui.quassum.com/

6. Fügen Sie das frisch Generierte Shapezu Ihrem Code hinzu.

struct MyCustomShape: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        let width = rect.size.width
        let height = rect.size.height
        path.move(to: CGPoint(x: 0.19277*width, y: 0.92051*height))
        path.addCurve(to: CGPoint(x: 0.2653*width, y: 0.98843*height), control1: CGPoint(x: 0.20687*width, y: 0.96579*height), control2: CGPoint(x: 0.23104*width, y: 0.98843*height))
        path.addCurve(to: CGPoint(x: 0.33219*width, y: 0.92647*height), control1: CGPoint(x: 0.29955*width, y: 0.98843*height), control2: CGPoint(x: 0.32185*width, y: 0.96777*height))
        path.addLine(to: CGPoint(x: 0.33219*width, y: 0.087*height))
        path.addCurve(to: CGPoint(x: 0.32684*width, y: 0.06301*height), control1: CGPoint(x: 0.33219*width, y: 0.07844*height), control2: CGPoint(x: 0.33033*width, y: 0.07008*height))
        path.addCurve(to: CGPoint(x: 0.24718*width, y: 0.0101*height), control1: CGPoint(x: 0.30949*width, y: 0.02773*height), control2: CGPoint(x: 0.28294*width, y: 0.0101*height))
        path.addCurve(to: CGPoint(x: 0.2008*width, y: 0.02081*height), control1: CGPoint(x: 0.23579*width, y: 0.0101*height), control2: CGPoint(x: 0.21869*width, y: 0.01038*height))
        path.addCurve(to: CGPoint(x: 0.00999*width, y: 0.19972*height), control1: CGPoint(x: 0.17119*width, y: 0.03807*height), control2: CGPoint(x: 0.10759*width, y: 0.0977*height))
        path.addCurve(to: CGPoint(x: 0.00999*width, y: 0.29059*height), control1: CGPoint(x: -0.00333*width, y: 0.23402*height), control2: CGPoint(x: -0.00333*width, y: 0.26431*height))
        path.addCurve(to: CGPoint(x: 0.05958*width, y: 0.31902*height), control1: CGPoint(x: 0.0233*width, y: 0.31686*height), control2: CGPoint(x: 0.03983*width, y: 0.32634*height))
        path.addLine(to: CGPoint(x: 0.18235*width, y: 0.21522*height))
        path.addCurve(to: CGPoint(x: 0.19176*width, y: 0.21836*height), control1: CGPoint(x: 0.18557*width, y: 0.21249*height), control2: CGPoint(x: 0.18979*width, y: 0.2139*height))
        path.addCurve(to: CGPoint(x: 0.19277*width, y: 0.2233*height), control1: CGPoint(x: 0.19242*width, y: 0.21985*height), control2: CGPoint(x: 0.19277*width, y: 0.22156*height))
        path.addLine(to: CGPoint(x: 0.19277*width, y: 0.92051*height))
        path.addLine(to: CGPoint(x: 0.19277*width, y: 0.92051*height))
        path.closeSubpath()
        path.move(to: CGPoint(x: 0.69057*width, y: 0.7981*height))
        path.addCurve(to: CGPoint(x: 0.97169*width, y: 0.34296*height), control1: CGPoint(x: 0.86713*width, y: 0.57524*height), control2: CGPoint(x: 0.96084*width, y: 0.42353*height))
        path.addCurve(to: CGPoint(x: 0.73689*width, y: 0.00042*height), control1: CGPoint(x: 1.01286*width, y: 0.03744*height), control2: CGPoint(x: 0.79508*width, y: 0.00549*height))
        path.addCurve(to: CGPoint(x: 0.54637*width, y: 0.09386*height), control1: CGPoint(x: 0.67965*width, y: -0.00457*height), control2: CGPoint(x: 0.60044*width, y: 0.03569*height))
        path.addCurve(to: CGPoint(x: 0.49384*width, y: 0.25608*height), control1: CGPoint(x: 0.50625*width, y: 0.13702*height), control2: CGPoint(x: 0.48874*width, y: 0.19109*height))
        path.addCurve(to: CGPoint(x: 0.54637*width, y: 0.32849*height), control1: CGPoint(x: 0.49732*width, y: 0.30435*height), control2: CGPoint(x: 0.51483*width, y: 0.32849*height))
        path.addCurve(to: CGPoint(x: 0.60648*width, y: 0.29057*height), control1: CGPoint(x: 0.56918*width, y: 0.32849*height), control2: CGPoint(x: 0.58922*width, y: 0.31585*height))
        path.addLine(to: CGPoint(x: 0.60647*width, y: 0.29056*height))
        path.addCurve(to: CGPoint(x: 0.6279*width, y: 0.24067*height), control1: CGPoint(x: 0.61618*width, y: 0.27632*height), control2: CGPoint(x: 0.6235*width, y: 0.25929*height))
        path.addCurve(to: CGPoint(x: 0.73689*width, y: 0.16131*height), control1: CGPoint(x: 0.6404*width, y: 0.18776*height), control2: CGPoint(x: 0.67673*width, y: 0.16131*height))
        path.addCurve(to: CGPoint(x: 0.80924*width, y: 0.39983*height), control1: CGPoint(x: 0.77971*width, y: 0.16131*height), control2: CGPoint(x: 0.88867*width, y: 0.21187*height))
        path.addCurve(to: CGPoint(x: 0.50041*width, y: 0.82587*height), control1: CGPoint(x: 0.77745*width, y: 0.47504*height), control2: CGPoint(x: 0.58125*width, y: 0.70046*height))
        path.addCurve(to: CGPoint(x: 0.48514*width, y: 0.9152*height), control1: CGPoint(x: 0.47311*width, y: 0.86822*height), control2: CGPoint(x: 0.48396*width, y: 0.90852*height))
        path.addCurve(to: CGPoint(x: 0.5197*width, y: 0.96465*height), control1: CGPoint(x: 0.48792*width, y: 0.93094*height), control2: CGPoint(x: 0.49944*width, y: 0.94742*height))
        path.addCurve(to: CGPoint(x: 0.53583*width, y: 0.97096*height), control1: CGPoint(x: 0.52455*width, y: 0.96877*height), control2: CGPoint(x: 0.53013*width, y: 0.97096*height))
        path.addLine(to: CGPoint(x: 0.94174*width, y: 0.97096*height))
        path.addCurve(to: CGPoint(x: 0.96928*width, y: 0.95989*height), control1: CGPoint(x: 0.95149*width, y: 0.97096*height), control2: CGPoint(x: 0.96104*width, y: 0.96712*height))
        path.addCurve(to: CGPoint(x: 0.99372*width, y: 0.89749*height), control1: CGPoint(x: 0.98557*width, y: 0.94557*height), control2: CGPoint(x: 0.99372*width, y: 0.92477*height))
        path.addCurve(to: CGPoint(x: 0.96211*width, y: 0.82232*height), control1: CGPoint(x: 0.99372*width, y: 0.86647*height), control2: CGPoint(x: 0.98318*width, y: 0.84142*height))
        path.addCurve(to: CGPoint(x: 0.94337*width, y: 0.81459*height), control1: CGPoint(x: 0.95654*width, y: 0.81728*height), control2: CGPoint(x: 0.95002*width, y: 0.81459*height))
        path.addLine(to: CGPoint(x: 0.69517*width, y: 0.81459*height))
        path.addCurve(to: CGPoint(x: 0.68833*width, y: 0.8051*height), control1: CGPoint(x: 0.69139*width, y: 0.81458*height), control2: CGPoint(x: 0.68833*width, y: 0.81033*height))
        path.addCurve(to: CGPoint(x: 0.69057*width, y: 0.7981*height), control1: CGPoint(x: 0.68833*width, y: 0.80243*height), control2: CGPoint(x: 0.68915*width, y: 0.79989*height))
        path.closeSubpath()
        return path
    }
}

8. Schließlich können wir alle Modifikatoren darauf anwenden wie auf ein normales ShapeObjekt und erhalten schöne Zahlen mit Tiefeneffekt.

MyCustomShape()
   .frame(width: 100, height: 100)
   .overlay(
  MyCustomShape()
    .fill(
    .shadow(.inner(color: bgl, radius: 5, x: -5, y: 5))
    .shadow(.inner(color: bgd, radius: 5, x: 5, y: -5)))
    .foregroundColor(colorbg))

Das ist es! Einfach und unkompliziert.

Stellen Sie sich vor, Sie müssten alle diese Codezeilen selbst schreiben. Ich hoffe, dass Sie dadurch etwas Zeit sparen, damit Sie es für interessante Codierungen verwenden können. Bis zum nächsten Mal!