ios - SwiftUI - 限制 View 内矩形的拖动

标签 ios swift swiftui

下面是我编写的用于拖动矩形的代码。我想将其拖动限制在给定 View 的边界内。即,如果用户尝试将矩形移动到 View 边框之外,它应该保持在边框边缘内。我尝试使用 GeometryReader 来获取矩形和外部 View 的矩形,但我无法限制拖动。请帮忙。

import SwiftUI

struct DragView: View {
    @State private var currentPosition: CGSize = .zero
    @State private var newPosition: CGSize = .zero
    @State private var parentRect: CGRect = .zero
    @State private var childRect: CGRect = .zero

    var body: some View {
            VStack {
                Rectangle().frame(width: 100, height: 100, alignment: .top)
                    .foregroundColor(.blue)
                    .offset(x: self.currentPosition.width, y: self.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)
                        }
                        .onEnded { value in
                            self.currentPosition = CGSize(width: value.translation.width + self.newPosition.width, height: value.translation.height + self.newPosition.height)
                            self.newPosition = self.currentPosition
                        }
                )
            }
            .frame(width: 300, height: 500, alignment: .center)
            .border(Color.black, width: 1)
            .background(GeometryGetter(rect: $parentRect))
    }
}

struct GeometryGetter: View {
    @Binding var rect: CGRect

    var body: some View {
        GeometryReader { geometry in
            Group { () -> AnyView in
                DispatchQueue.main.async {
                    self.rect = geometry.frame(in: .global)
                }
                return AnyView(Color.clear)
            }
        }
    }
}

最佳答案

看看这个:

struct ContentView: View {
    @State private var currentPosition: CGSize = .zero
    @State private var newPosition: CGSize = .zero
    @State private var parentRect: CGRect = .zero
    @State private var childRect: CGRect = .zero

    func correctPostion() {
        print(self.currentPosition)
        if self.currentPosition.width > 100 {
            self.currentPosition.width = 100
        }
        if self.currentPosition.height > 200 {
            self.currentPosition.height = 200
        }
        if self.currentPosition.width < -100 {
            self.currentPosition.width = -100
        }
        if self.currentPosition.height < -200 {
            self.currentPosition.height = -200
        }
    }

    var body: some View {
            VStack {
                Rectangle().frame(width: 100, height: 100, alignment: .top)
                    .foregroundColor(.blue)
                    .offset(x: self.currentPosition.width, y: self.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()

                            self.newPosition = self.currentPosition
                        }
                )
            }
            .frame(width: 300, height: 500, alignment: .center)
            .border(Color.black, width: 1)
            .background(GeometryGetter(rect: $parentRect))
    }
}

struct GeometryGetter: View {
    @Binding var rect: CGRect

    var body: some View {
        GeometryReader { geometry in
            Group { () -> AnyView in
                DispatchQueue.main.async {
                    self.rect = geometry.frame(in: .global)
                }
                return AnyView(Color.clear)
            }
        }
    }
}

关于ios - SwiftUI - 限制 View 内矩形的拖动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60975665/

相关文章:

swift - 在 SwiftUI 中,如何以高性能绘制阴影?

SwiftUI ForEach 数组索引不呈现

ios - Xcode 6 - 用于通用图像支持的 xcassets

ios - 围绕中心点旋转 CGPoint

ios - UIImage不释放内存

ios - SwiftUI:仅当 ScrollView 超过屏幕高度时才可滚动

ios - getter 和 setter 自定义并发队列同步的竞争条件

swift - 应用内购买 Swift Game

ios - Swift - 通知观察者被多次调用

swift - 为什么使用 EXC_BAD_INSTRUCTION 将 minWidth 设置为 .infinity 会使 SwiftUI 应用程序崩溃?