I have a circle and I want to place small rectanlges at the edge of the circle. I want rectangles to placed on edge by only defining the angle. i.e if angle is 90, rectangle should be on top center of the circle. If say 120, it should be placed a little ahead of 90 degree's rectangle along with a little tilt, so rectangle and circle should be in sync. I have tried alot to solve this, but I am unable to crack this yet.
Below is the code that I've written so far. Its basically a starter code, nothing more.
struct ContentView: View {
var body: some View {
GeometryReader { geo in
VStack {
ZStack {
Circle()
.stroke(lineWidth: 10)
.frame(width: 220)
Rectangle()
.frame(width: 15, height: 50)
.position(x: 0, y: 0)
} //ZStack
.frame(width: 220, height: 220, alignment: .center)
.background(Color.green)
} //VStack
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.blue)
}
}
}
Any help would be appreciated
CodePudding user response:
I would suggest applying .offset
followed by .rotationEffect
to the rectangles.
Like this:
struct ContentView: View {
let radius: CGFloat = 110
let tickMarkLength: CGFloat = 50
private func tickMark(degrees: CGFloat) -> some View {
Rectangle()
.frame(width: 15, height: tickMarkLength)
.offset(y: -radius - (tickMarkLength / 2))
.rotationEffect(.degrees(degrees - 90))
}
var body: some View {
ZStack {
Circle()
.stroke(lineWidth: 10)
.frame(width: radius * 2, height: radius * 2)
.background(
Circle().fill(.green)
)
tickMark(degrees: 90)
tickMark(degrees: 120)
}
.frame(
width: (radius * 2) (tickMarkLength * 2),
height: (radius * 2) (tickMarkLength * 2)
)
.background(.blue)
}
}
In the code you provided in the question, you had a GeometryReader
, although it didn't seem to be serving any purpose. However, if you were intending to derive the radius of the circle from the size of the frame it is contained in, then this is possible too. A few small adaptions are needed:
struct ContentView: View {
let tickMarkLength: CGFloat = 50
private func tickMark(radius: CGFloat, degrees: CGFloat) -> some View {
// implementation as before
}
var body: some View {
GeometryReader { geo in
let radius = (geo.size.height / 2) - tickMarkLength
ZStack {
Circle()
// modifiers as before
tickMark(radius: radius, degrees: 90)
tickMark(radius: radius, degrees: 120)
}
.frame(width: geo.size.width, height: geo.size.height)
}
.frame(width: 320, height: 320) // just an example
.background(.blue)
}
}