'SwiftUI create View and func with button tapped. Is this possible?
When the "Add Circle" button is pressed, Circle() will be created in VStack.
Clicking "Add Function for Circle" button will add frame, trim, stroke functions to Circle(). Do you think this is possible? Edit: I added code.
Can't add it directly like a View without ForEach? As you can see, there is no Circle() on my code screen, and when I press the button, I want to create a circle on the code screen (SwiftUI file) and preview screen.
Code:
struct SampleView: View {
var body: some View {
VStack(spacing: 20) {
// Circle here....
//Circle()
Button(action: {
//Add Circle
//Circle()
}) {
Text("Add Circle")
}
Button(action: {
//Add Function
//frame, stroke, trim... etc.
}) {
Text("Add Function for Circle")
}
}
}
}
Solution 1:[1]
This code does what you want. It chooses a random color. You can expand the CircleStyle struct as you need to and add border, shadow and other styles to it.
struct CircleStyle {
let id: Int
let color: Color
let shadowColor: Color
let shadowRadius: Double
}
struct ContentView: View {
let colorList: [Color] = [.red, .blue, .green, .yellow]
@State var shapeList = [CircleStyle]()
@State var maxId = 0
var body: some View {
VStack {
// Here the circles are stacked
ForEach(shapeList, id: \.id) { shapeStyle in
Circle()
.foregroundColor(shapeStyle.color)
.shadow(color: shapeStyle.shadowColor, radius: shapeStyle.shadowRadius)
}
Button(action: {
// Here the circle styles are created
// You can also edit the styles with another action
maxId += 1
self.shapeList.append(CircleStyle(id: maxId, color: colorList.randomElement()!, shadowColor: colorList.randomElement()!, shadowRadius: Double.random(in: 0...20)))
}) {
Text("Add")
}
}
}
}
It looks like this:

Solution 2:[2]
you can easily add buttons to the VStack, as for
functions as you call modifiers, you can apply the same principle,
using some @State var and add them to the desired button. It's up to you
which button you want to add modifiers to.
Adding buttons to the VStack:
struct ContentView: View {
@State var circles = 0
var body: some View {
VStack (spacing: 20){
ForEach(0..<circles, id: \.self) { n in
Circle().frame(width: 44, height: 44) // <-- replace 44 with var
}
Button(action: { circles += 1 } ) {
Text("Add circle")
}
Button(action: {
// you can do the rest, using var for use in frame width etc...
} ) {
Text("Add function for circle")
}
}
}
}
EDIT-1: only 1 button
struct ContentView: View {
@State var showCircles = false
@State var w: CGFloat = 66
@State var h: CGFloat = 66
var body: some View {
VStack (spacing: 20){
if showCircles {
Circle().frame(width: w, height: h)
}
Button(action: { showCircles = true } ) {
Text("Add circle")
}
Button(action: {
w = 22
h = 22
} ) {
Text("Add function for circle")
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |

