swiftUI, перемещая представление туда, где я нажал - PullRequest
1 голос
/ 14 июля 2020

Я работаю над перемещением обзора туда, где я коснулся. В моем коде ниже моя цель перемещается - redCircleView() в прямоугольник, который я коснулся.

Сначала я попытался получить координату того места, где коснулся пользователь, и передать эту координату в смещение redCircleView (). Прикол c, который я пытался использовать, это:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let position = touch.location(in: view)
     
    }
}

Но у меня возникла проблема с вызовом и объявлением класса для встраивания этого развлечения c в ContentView.swift

Поэтому вместо этого я попытался получить координаты каждого прямоугольника при касании. Вот мой текущий код:

struct ContentView: View {
    @State private var currentPos: CGSize = .zero
    @State private var newPos: CGSize = .zero
       
    var body: some View {
        GeometryReader { usa in
            ZStack{
            VStack{
                HStack{
                    Rectangle().frame(width: 100, height: 100).onTapGesture {
                                        let frame = usa.frame(in: CoordinateSpace.local)
                                       self.currentPos.width = frame.size.width
                                       self.currentPos.height = frame.size.height
                    }
                    Spacer()
                     Rectangle().frame(width: 100, height: 100).onTapGesture {
                                        let frame = usa.frame(in: CoordinateSpace.local)
                                        self.currentPos.width = frame.size.width
                                        self.currentPos.height = frame.size.height
                     }
                }
                
                HStack{
                     Rectangle().frame(width: 100, height: 100).onTapGesture {
                                        let frame = usa.frame(in: CoordinateSpace.local)
                                        self.currentPos.width = frame.size.width
                                        self.currentPos.height = frame.size.height
                     }
                    Spacer()
                    Rectangle().frame(width: 100, height: 100).onTapGesture {
                                    let frame = usa.frame(in: CoordinateSpace.local)
                                       self.currentPos.width = frame.size.width
                                       self.currentPos.height = frame.size.height
                    }
                }
            }
                //end of VStack    
                redCircleView()
                     .offset(x: self.currentPos.width, y: self.currentPos.height)
                     .gesture(DragGesture()
                         .onChanged { value in
                             self.currentPos = CGSize(width: value.translation.width + self.newPos.width, height: value.translation.height + self.newPos.height)
                            
                     }
                         .onEnded { value in
                             self.currentPos = CGSize(width: value.translation.width + self.newPos.width, height: value.translation.height + self.newPos.height)
                           
                             self.newPos = self.currentPos
                         }
            )
            
            }
        }
        }
        
    }

struct redCircleView: View {
    var body: some View {
        Circle()
        .frame(width: 100, height: 100)
       .foregroundColor(Color.red)
    }
}

Но проблема здесь в том, что когда я касаюсь прямоугольника, redCircleView () исчезает, не перемещаясь в прямоугольник, где я коснулся. Думаю, проблема в том, чтобы получить координату прямоугольника, на который я записал, но понятия не имел, как это исправить.

1 Ответ

1 голос
/ 14 июля 2020

Вот возможное решение. Ему нужно захватить кадр каждого поля в том же координатном пространстве, что и круг, а затем вычислить необходимое перемещение. (Также был произведен рефакторинг извлечения для вспомогательной функции, чтобы избежать дублирования кода).

Протестировано с Xcode 11.4 / iOS 13.4

демо

struct ContentView: View {
    @State private var currentPos: CGSize = .zero
    @State private var newPos: CGSize = .zero

    private func generateBox(in usa: GeometryProxy) -> some View {
        Rectangle().frame(width: 100, height: 100).overlay(GeometryReader { gp in
            Color.black.onTapGesture {
                let area = usa.frame(in: CoordinateSpace.global)
                let frame = gp.frame(in: CoordinateSpace.global)
                let position = CGSize(width: frame.midX - area.midX, height: frame.midY - area.midY)

                self.newPos = position
                withAnimation {
                    self.currentPos = position
                }
            }
        })
    }

    var body: some View {
        GeometryReader { usa in
            ZStack{
                VStack{
                    HStack{
                        self.generateBox(in: usa)
                        Spacer()
                        self.generateBox(in: usa)
                    }

                    HStack{
                        self.generateBox(in: usa)
                        Spacer()
                        self.generateBox(in: usa)
                    }
                }
                //end of VStack
                redCircleView()
                    .offset(x: self.currentPos.width, y: self.currentPos.height)
                    .gesture(DragGesture()
                        .onChanged { value in
                            self.currentPos = CGSize(width: value.translation.width + self.newPos.width, height: value.translation.height + self.newPos.height)

                    }
                    .onEnded { value in
                        self.currentPos = CGSize(width: value.translation.width + self.newPos.width, height: value.translation.height + self.newPos.height)

                        self.newPos = self.currentPos
                        }
                )

            }
        }
    }
}
...