Как сделать кнопку перетаскиваемой / перемещаемой с помощью SwiftUI? - PullRequest
1 голос
/ 17 апреля 2020

Я пытаюсь сделать кнопку подвижной с помощью SwiftUI. Из того, как это выглядит, должно работать. Я пытался поместить Button with Text в другой ZStack, и на секунду он заработал, но как только я отпустил кнопку, перетаскивание прекратилось, и я больше не мог перетаскивать. Я заметил, что кран оставался в центре, несмотря на перемещение кнопки. Также перетаскивание выглядело глючным.

 struct CircleButton: View {
@State private var dragAmount = CGSize.zero
var body: some View {
    ZStack {
        Button(action: performAction){
            ZStack {
                Circle()
                    .foregroundColor(.blue)
                    .frame(width: 100, height: 100)
                Text("Move me")
                    .foregroundColor(.white)
                    .font(.system(.caption, design: .serif))
            }
        }
        .animation(.default)
        .offset(self.dragAmount)
    }
    .gesture(
        DragGesture()
            .onChanged { self.dragAmount = $0.translation})
}

func performAction(){
    print("button pressed")
 }
}

Я пробовал это:

struct CircleButton: View {
@State private var dragAmount = CGSize.zero
var body: some View {
    ZStack {
        ZStack {
            Button(action: performAction){
                Circle()
                    .foregroundColor(.blue)
                    .frame(width: 100, height: 100)
            }
            Text("Tap me")
        }
        .offset(self.dragAmount)
        .animation(.default)
    }
    .gesture(
        DragGesture()
            .onChanged{ self.dragAmount = $0.translation})
}

func performAction(){
    print("button pressed")
 }
}

Ответы [ 2 ]

1 голос
/ 17 апреля 2020

как насчет чего-то другого и краткого:

import SwiftUI

struct ContentView: View {
var body: some View {
    CircleButton()
}
}

struct CircleButton: View {

@State private var pos = CGPoint(x:222,y:222) // just for testing

var body: some View {
    theButton.position(self.pos).highPriorityGesture(self.drag)
}

var theButton: some View {
    ZStack {
        Circle()
            .foregroundColor(.blue)
            .frame(width: 100, height: 100)
            .onTapGesture { self.performAction() }
        Text("Tap me")
            .foregroundColor(.white)
            .font(.system(.caption, design: .serif))
    }
}

func performAction(){
    print("button pressed")
}

var drag: some Gesture {
    DragGesture().onChanged { value in self.pos = CGPoint(x: value.location.x, y: value.location.y)}
}
}
1 голос
/ 17 апреля 2020

Вот демонстрация возможного подхода. Протестировано и работает с Xcode 11.4 / iOS 13.4

demo

См. Также встроенные примечания.

struct CircleButton: View {
    @State private var dragAmount: CGPoint? = nil
    var body: some View {
        GeometryReader { gp in // just to center initial position
            ZStack {
                Button(action: self.performAction){
                    ZStack {
                        Circle()
                            .foregroundColor(.blue)
                            .frame(width: 100, height: 100)
                        Text("Move me")
                            .foregroundColor(.white)
                            .font(.system(.caption, design: .serif))
                    }
                }
                .animation(.default)
                .position(self.dragAmount == nil ?
                            CGPoint(x: gp.size.width / 2, y: gp.size.height / 2) :
                            self.dragAmount!)
                .highPriorityGesture(  // << to do no action on drag !!
                    DragGesture()
                        .onChanged { self.dragAmount = $0.location})
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity) // full space
        }
    }

    func performAction(){
        print("button pressed")
    }
}
...