微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在拖动手势时将矩形限制为屏幕边缘

如何解决在拖动手势时将矩形限制为屏幕边缘

我刚刚开始使用SwiftUI,我希望能找到最好的方法解决在拖动手势期间将此矩形保持在屏幕边界的问题。现在,它从边缘移出,直到到达正方形的中间(我认为是因为我正在使用CGPoint)。

我尝试做一些数学运算来限制矩形,但矩形仅在左侧成功,但这似乎是一种糟糕的方法,并且不能考虑屏幕尺寸的变化。有人可以帮忙吗?

struct ContentView: View {
    @State private var pogPosition = CGPoint()
    
    var body: some View {
        PogSound()
            .position(pogPosition)
            .gesture(
                DragGesture()
                    .onChanged { value in
                        self.pogPosition = value.location
                        
                        // Poor solve
                        if(self.pogPosition.x < 36) {
                            self.pogPosition.x = 36
                        }
                }
                .onEnded { value in
                    print(value.location)
                }
        )
    }
}

enter image description here

解决方法

这里是一种可能方法的演示(对于任何视图,都会导致动态读取视图框架)。

演示并通过Xcode 12 / iOS 14进行了测试

enter image description here

struct ViewSizeKey: PreferenceKey {
    static var defaultValue = CGSize.zero
    static func reduce(value: inout Value,nextValue: () -> Value) {
        value = nextValue()
    }
}

struct ContentView: View {
    @State private var pogPosition = CGPoint()
    @State private var size = CGSize.zero

    var body: some View {
        GeometryReader { gp in
            PogSound()
                .background(GeometryReader {
                    Color.clear
                        .preference(key: ViewSizeKey.self,value: $0.frame(in: .local).size)
                })
                .onPreferenceChange(ViewSizeKey.self) {
                    self.size = $0
                }
                .position(pogPosition)
                .gesture(
                    DragGesture()
                        .onChanged { value in
                            let rect = gp.frame(in: .local)
                                .inset(by: UIEdgeInsets(top: size.height / 2.0,left: size.width / 2.0,bottom: size.height / 2.0,right: size.width / 2.0))
                            if rect.contains(value.location) {
                                self.pogPosition = value.location
                            }
                        }
                        .onEnded { value in
                            print(value.location)
                        }
            )
            .onAppear {
                let rect = gp.frame(in: .local)
                self.pogPosition = CGPoint(x: rect.midX,y: rect.midY)
            }
        }.edgesIgnoringSafeArea(.all)
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。