Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Rough attempt at creating a container view that lays out its children in a circle #SwiftUI
struct ContentView: View {
@State var count: Int = 3
var body: some View {
return NavigationView {
VStack(spacing: 50) {
HStack {
Button(action: { self.count += 1 }) {
Text("Add")
}
Button(action: { self.count -= 1 }) {
Text("Remove")
}
}
Circular {
ForEach(0..<max(0, count)) { i in
Color.green
.frame(width: 30, height: 30)
.clipShape(Circle())
.overlay(Text("\(i)").font(.headline).foregroundColor(.white).allowsTightening(true))
.shadow(radius: 3)
}
}
}.navigationBarTitle(Text("Full Circle"))
}
}
}
struct Circular<Items: View>: View {
let items: [AnyView]
let radius: Double = 100
init<D, C0: View>(@ViewBuilder content: () -> Items) where Items == ForEach<D, C0> {
let fe = content()
self.items = fe.data.map { AnyView(fe.content($0.identifiedValue)) }
}
var body: some View {
return ZStack {
ForEach(0..<items.count) { idx in
self.items[idx].modifier(self.positionModifier(at: idx))
}
}
.background(Circle().foregroundColor(.gray).opacity(0.2))
.frame(width: Length(2*radius), height: Length(2*radius))
.animation(.fluidSpring())
}
func positionModifier(at index: Int) -> _PositionLayout {
let r = (2*Double.pi / Double(items.count)) * Double(index)
return _PositionLayout(position: CGPoint(x: sin(r)*radius+radius, y: cos(r)*radius+radius))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.