Ufuk Köşker
Ufuk Köşker

Reputation: 1480

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.

enter image description here

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")
        }
      }
    }
}

Upvotes: 1

Views: 1267

Answers (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")
            }
        }
    }
    
}

Upvotes: 0

Frederik Mrozek
Frederik Mrozek

Reputation: 175

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: image

Upvotes: 1

Related Questions