在 SwiftUI 中调整形状大小时如何使用 DragGesture() 设置大小限制?

How to set size limit using DragGesture() when resizing a shape in SwiftUI?

我正在尝试使用 DragGesture() 创建可调整大小的形状,但我找不到在拖动时限制形状大小的方法。

这是当前输出。 我不想越过绿线。 https://imgur.com/a/MgyLdpj

这是当前代码:

struct ContentView: View {
    
    var body: some View {
        VStack {
            CustomDraggableComponent()
                .frame(width: 350, height: 350, alignment: .center)
                .border(Color.green, width: 5)
        }
    }
    
    
    
    struct CustomDraggableComponent: View {
        @State var height: CGFloat = 200
        @State var width: CGFloat = 200
        
        
        
        var body: some View {
            VStack {
                Rectangle()
                    .fill(Color.red)
                    .frame(minWidth: width, maxWidth: width, minHeight: height, maxHeight: height)
                
                HStack {
                    Spacer()
                    Rectangle()
                        .fill(Color.gray)
                        .frame(width: 80, height: 30)
                        .cornerRadius(10)
                        .overlay(Text("Drag"))
                        .gesture(
                            DragGesture()
                                .onChanged { value in
                                    height = max(200, height + value.translation.height)
                                    width = max(200, height + value.translation.width)
                                }
                        )
                    Spacer()
                }
            }
        }
    }
}

你只需要将第二个形状放在第一个形状的叠加层上,然后它会自动限制在需要的区域,比如

var body: some View {
    Rectangle()
        .fill(Color.red)
        .frame(minWidth: width, maxWidth: width, minHeight: height, maxHeight: height)
        .overlay(
            Rectangle()
                .fill(Color.gray)
                .frame(width: 80, height: 30)
                .cornerRadius(10)
                .overlay(Text("Drag"))
                .gesture(
                    DragGesture()
                        .onChanged { value in
                            height = max(200, height + value.translation.height)
                            width = max(200, height + value.translation.width)
                        }
                )
        )
}

您可以使用 GeometryReader 获取子视图大小并使用最小条件限制大小。

struct CustomDraggableComponent: View {
        @State var height: CGFloat = 200
        @State var width: CGFloat = 200
        
        @State private var maxWidth = 0
        @State private var maxHeight = 0
        
        var body: some View {
            GeometryReader { geo in
                VStack(alignment: .center) {
                    Rectangle()
                        .fill(Color.red)
                        .frame(minWidth: width, maxWidth: width, minHeight: height, maxHeight: height)
                    
                    HStack {
                        Spacer()
                        Rectangle()
                            .fill(Color.gray)
                            .frame(width: 80, height: 30)
                            .cornerRadius(10)
                            .overlay(Text("Drag"))
                            .gesture(
                                DragGesture()
                                    .onChanged { value in
                                        // This code allows resizing view min 200 and max to parent view size
                                        height = min(max(200, height + value.translation.height), geo.size.height - 45) // 45 for Drag button height + padding
                                        width = min(max(200, height + value.translation.width), geo.size.width)
                                    }
                            )
                        Spacer()
                    }
                } .frame(width: geo.size.width, height: geo.size.height)
            }
        }
    }