Выбор ближайшей кнопки в соответствии с положением пальца в SwiftUI - PullRequest
1 голос
/ 30 марта 2020

У меня есть несколько кнопок подряд, и я хочу выбрать ближайшую в соответствии с X-направлением пальца на экране.

enter image description here

У меня есть следующий код ...

struct SelectTheKey: View {

    private var sArray = ["e", "s", "p", "b", "k"]
    @State var isShowPopup: Bool = false
    @State private var dragPosition = CGPoint.zero

    var body: some View {

        VStack() {
            Spacer()
            Text("global: \(self.dragPosition.x) : \(self.dragPosition.y)")

            if isShowPopup {
                HStack(spacing: 5) {
                    ForEach(0..<sArray.count) { id in
                        Text("\(self.sArray[id])").fontWeight(.bold).font(.title)
                            .foregroundColor(.white)
                            .padding()
                            .background(id == 2 ? Color.red : Color.blue)
                            .cornerRadius(5)
                    }
                }.offset(x:40, y:0)
            }

            Text("A").frame(width: 60, height: 90)
                .foregroundColor(.white)
                .background(Color.purple)
                .shadow(radius: 2)
                .padding(10)
                .gesture(DragGesture(minimumDistance: 2, coordinateSpace: .global)
                    .onChanged { dragGesture in
                        self.dragPosition = dragGesture.location
                        if !self.isShowPopup {self.isShowPopup.toggle()}
                }
                .onEnded {finalValue in
                    if self.isShowPopup {self.isShowPopup.toggle()}
                })
        }
    }
}

1 Ответ

1 голос
/ 30 марта 2020

Здесь возможен подход. Протестировано с Xcode 11.4 / iOS 13.4

demo

struct SelectTheKey: View {

    private var sArray = ["e", "s", "p", "b", "k"]
    @State var isShowPopup: Bool = false
    @State private var dragPosition = CGPoint.zero

    @State private var rects = [Int: CGRect]()
    @State private var selected = -1
    var body: some View {

        VStack() {
            Spacer()
            Text("global: \(self.dragPosition.x) : \(self.dragPosition.y)")

            if isShowPopup {
                HStack(spacing: 5) {
                    ForEach(0..<sArray.count) { id in
                        Text("\(self.sArray[id])").fontWeight(.bold).font(.title)
                            .foregroundColor(.white)
                            .padding()
                            .background(id == self.selected ? Color.red : Color.blue)
                            .cornerRadius(5)
                            .background(self.rectReader(for: id))
                    }
                }.offset(x:40, y:0)
            }

            Text("A").frame(width: 60, height: 90)
                .foregroundColor(.white)
                .background(Color.purple)
                .shadow(radius: 2)
                .padding(10)
                .gesture(DragGesture(minimumDistance: 2, coordinateSpace: .global)
                    .onChanged { dragGesture in
                        self.dragPosition = dragGesture.location
                        if let (id, _) = self.rects.first(where: { (_, value) -> Bool in
                            value.minX < dragGesture.location.x && value.maxX > dragGesture.location.x
                        }) { self.selected = id }

                        if !self.isShowPopup {self.isShowPopup.toggle()}
                }
                .onEnded {finalValue in
                    if self.isShowPopup {self.isShowPopup.toggle()}
                })
        }
    }

    func rectReader(for key: Int) -> some View {
        return GeometryReader { gp -> AnyView in
            let rect = gp.frame(in: .global)
            DispatchQueue.main.async {
                self.rects[key] = rect
            }
            return AnyView(Rectangle().fill(Color.clear))
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...