按下按钮时在屏幕上的某个位置动态放置形状 - SwiftUI

卡斯帕

这是我之前问过的一个问题,但我正在编辑它以使其更容易获得帮助。

我正在尝试创建一个应用程序,您可以在其中拖动Circle()网格上的 a,并跟踪该 的 (x,y) 坐标Circle()我的目标是把它Circle()放在 (x,y) 位置,把它留在那里,然后生成一个新的Circle()来移动。

这是代码...

struct GridView: View {

//tracking position and boundary
@State private var currentPosition: CGSize = .zero
@State private var newPosition: CGSize = .zero
@State private var parentRect: CGRect = .zero
@State private var childRect: CGRect = .zero

//convert negative y value to positive and positive to negative
@State public var xVal: Int = 0
@State public var yVal: Int = 0

@State public var questionCount: Int = 1

//boundary for eisenhower matrix
func correctPostion() {
    print(self.currentPosition)
    if self.currentPosition.width > 200 {
        self.currentPosition.width = 200
    }
    if self.currentPosition.height > 200 {
        self.currentPosition.height = 200
    }
    if self.currentPosition.width < -200 {
        self.currentPosition.width = -200
    }
    if self.currentPosition.height < -200 {
        self.currentPosition.height = -200
    }
}

var body: some View {
    return
        ZStack {
            
            GeometryReader { geo in
                Text("current position: \n(X: \(xVal) Y: \(yVal))")
                    .position(x: geo.size.width / 2, y: 75)
                    .font(.title)
                    .multilineTextAlignment(.center)
                
                Button(action: {
                    //TODO: place circle
                    
                    //increase number of circles
                    self.questionCount += 1
                    
                    //reset the values
                    self.currentPosition = .zero
                    self.newPosition = .zero
                    self.xVal = 0
                    self.yVal = 0
                    
                }, label: {
                    Circle()
                        .overlay(
                            Text("Place")
                                .font(.title2)
                                .bold()
                                .foregroundColor(.white))
                })
                .frame(width: 75, height: 75, alignment: .center)
                .position(x: geo.size.width / 2, y: geo.size.height - 100)
            }
            
            VStack{
                ZStack {
                    //My attempt at creating multiple Circles() based on the count
                    //of questions which increases on the button press
                    ForEach(0 ..< questionCount, id: \.self) { _ in
                        Circle()
                            .overlay(Text("\(questionCount)").font(.title).foregroundColor(.white))
                            .frame(width: 35, height: 35, alignment: .center)
                            .foregroundColor(.red)
                            .offset(x: self.currentPosition.width, y: self.currentPosition.height)
                            .background(GeometryGetter(rect: $childRect))
                    // end of my attempt
                            
                            //ability to drag and track the position of the circle
                            .gesture(DragGesture(minimumDistance: 0, coordinateSpace: .global)
                                    .onChanged { value in
                                        self.currentPosition = CGSize(width: value.translation.width + self.newPosition.width, height: value.translation.height + self.newPosition.height)
                                        
                                        self.correctPostion()
                                    }
                                    .onEnded { value in
                                        self.currentPosition = CGSize(width: value.translation.width + self.newPosition.width, height: value.translation.height + self.newPosition.height)
                                        
                                        self.correctPostion()
                                        
                                        xVal = Int(self.currentPosition.width)
                                        yVal = Int(self.currentPosition.height) - (Int(self.currentPosition.height) * 2)
                                        
                                        self.newPosition = self.currentPosition
                                    }
                            
                            )
                    }
                }
                .frame(width: 400, height: 400, alignment: .center)
                .border(Color.black, width: 3)
                .background(GeometryGetter(rect: $parentRect))
               
            }
            
        }
}

}

我想放置Circle()xValyVal位置,并离开那里,当我按下按钮,然后生成一个新的Circle(),我可以做同样的事情。

有没有办法做到这一点?

jnpdx

如果这是我的项目,我会进一步重构它以将每个圆圈移动到它自己的视图中,但这应该会让你开始。基本概念是存储一个圆数组(我创建了一个名为 的类型PlacedCircle)并将它们与当前圆一起呈现。您可以使用放置的圆形数组的大小,而不是使用变量来计算问题。

struct PlacedCircle {
    var id = UUID()
    var number: Int
    var position: CGSize
}

struct ContentView: View {
    
    //tracking position and boundary
    @State private var currentPosition: CGSize = .zero
    @State private var newPosition: CGSize = .zero
    @State private var parentRect: CGRect = .zero
    @State private var childRect: CGRect = .zero

    //convert negative y value to positive and positive to negative
    @State public var xVal: Int = 0
    @State public var yVal: Int = 0
    
    @State public var placedCircles : [PlacedCircle] = []  //<-- Here

    //boundary for eisenhower matrix
    func correctPostion() {
        print(self.currentPosition)
        if self.currentPosition.width > 200 {
            self.currentPosition.width = 200
        }
        if self.currentPosition.height > 200 {
            self.currentPosition.height = 200
        }
        if self.currentPosition.width < -200 {
            self.currentPosition.width = -200
        }
        if self.currentPosition.height < -200 {
            self.currentPosition.height = -200
        }
    }

    var body: some View {
        return
            ZStack {
                
                GeometryReader { geo in
                    Text("current position: \n(X: \(xVal) Y: \(yVal))")
                        .position(x: geo.size.width / 2, y: 75)
                        .font(.title)
                        .multilineTextAlignment(.center)
                    
                    Button(action: {
                        self.placedCircles.append(PlacedCircle(number: placedCircles.count + 1, position: currentPosition)) //<-- Here
                        
                        //reset the values
                        self.currentPosition = .zero
                        self.newPosition = .zero
                        self.xVal = 0
                        self.yVal = 0
                        
                    }, label: {
                        Circle()
                            .overlay(
                                Text("Place")
                                    .font(.title2)
                                    .bold()
                                    .foregroundColor(.white))
                    })
                    .frame(width: 75, height: 75, alignment: .center)
                    .position(x: geo.size.width / 2, y: geo.size.height - 100)
                }
                
                VStack{
                    ZStack {
                        //The current circle
                        Circle()
                            .overlay(Text("\(placedCircles.count + 1)").font(.title).foregroundColor(.white))
                        .frame(width: 35, height: 35, alignment: .center)
                        .foregroundColor(.red)
                        .offset(x: currentPosition.width, y: currentPosition.height)
                            .background(GeometryGetter(rect: $childRect))

                        .gesture(DragGesture(minimumDistance: 0, coordinateSpace: .global)
                                .onChanged { value in
                                    self.currentPosition = CGSize(width: value.translation.width + self.newPosition.width, height: value.translation.height + self.newPosition.height)
                                    
                                    self.correctPostion()
                                }
                                .onEnded { value in
                                    self.currentPosition = CGSize(width: value.translation.width + self.newPosition.width, height: value.translation.height + self.newPosition.height)
                                    
                                    self.correctPostion()
                                    
                                    xVal = Int(self.currentPosition.width)
                                    yVal = Int(self.currentPosition.height) - (Int(self.currentPosition.height) * 2)
                                    
                                    self.newPosition = self.currentPosition
                                }
                        
                        )
                        
                        ForEach(placedCircles, id: \.id) { (placed : PlacedCircle) in
                            Circle()
                                .overlay(Text("\(placed.number)").font(.title).foregroundColor(.white))
                                .frame(width: 35, height: 35, alignment: .center)
                                .foregroundColor(.red)
                                .offset(x: placed.position.width, y: placed.position.height)
                                //.background(GeometryGetter(rect: $childRect))
                        }
                    }
                    .frame(width: 400, height: 400, alignment: .center)
                    .border(Color.black, width: 3)
                    .background(GeometryGetter(rect: $parentRect))
                   
                }
                
            }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章