Skip to content

Instantly share code, notes, and snippets.

@heestand-xyz
Last active August 27, 2022 17:20
Show Gist options
  • Save heestand-xyz/465128990d6f893544e1a391894f5d97 to your computer and use it in GitHub Desktop.
Save heestand-xyz/465128990d6f893544e1a391894f5d97 to your computer and use it in GitHub Desktop.
Spline Demo in SwiftUI
//
// ContentView.swift
// Spline Demo
//
// Created by Anton Heestand on 2022-08-27.
//
import SwiftUI
struct ContentView: View {
@State private var leadingFrame: CGRect?
@State private var trailingFrame: CGRect?
@State private var location: CGPoint?
@State private var interacting: Bool = false
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 16, style: .continuous)
.read(frame: $leadingFrame)
.frame(width: 100,
height: 100)
.offset(x: -200)
RoundedRectangle(cornerRadius: 16, style: .continuous)
.foregroundColor(interacting ? .accentColor : .primary)
.read(frame: $trailingFrame)
.frame(width: 100,
height: 100)
.offset(x: -50,
y: -50)
.offset(x: location?.x ?? 200,
y: location?.y ?? -100)
.gesture(
DragGesture()
.onChanged { value in
interacting = true
location = value.location
}
.onEnded { _ in
interacting = false
}
)
Path { path in
guard let leadingFrame,
let trailingFrame
else { return }
let leadingPoint = CGPoint(x: leadingFrame.maxX,
y: leadingFrame.midY)
let trailingPoint = CGPoint(x: trailingFrame.minX,
y: trailingFrame.midY)
let controlPoint1 = CGPoint(x: (leadingPoint.x + trailingPoint.x) / 2,
y: leadingPoint.y)
let controlPoint2 = CGPoint(x: (leadingPoint.x + trailingPoint.x) / 2,
y: trailingPoint.y)
path.move(to: leadingPoint)
path.addCurve(to: trailingPoint,
control1: controlPoint1,
control2: controlPoint2)
}
.stroke()
}
.coordinateSpace(name: "main")
.frame(maxWidth: .infinity,
maxHeight: .infinity)
}
}
extension View {
func read(frame: Binding<CGRect?>) -> some View {
self.background {
GeometryReader { geometry in
Color.clear
.onAppear {
frame.wrappedValue = geometry.frame(in: .named("main"))
}
.onChange(of: geometry.frame(in: .named("main"))) { newFrame in
frame.wrappedValue = newFrame
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment