简体   繁体   中英

How to align ZStack View to elements in a view below it

I have some vstack views, and a zstack view (its a dropdown menu).

在此处输入图像描述

I need the top of the zstack view to align itself perfectly with the text of VStack 2 Text like this

在此处输入图像描述

I think I need to utilize named coordinate spaces, but I have been unsuccessful in accomplishing this

You can use a custom alignmentGuide :

在此处输入图像描述

struct ContentView: View {
    
    @State private var selection: Int = 1
    
    var body: some View {
        ZStack(alignment: .myAlignment) { // important
            VStack(spacing: 0) {
                
                Text("VStack 1 - press long")
                    .padding()
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
                    .background(.blue)
                
                Text("VStack 2")
                    .padding(.trailing)
                    // defining alignment point on "VStack 2" Text
                    .alignmentGuide(.myVerticalAlignment, computeValue: { d in
                        d[VerticalAlignment.top]
                    })
                    .alignmentGuide(.myHorizontalAlignment, computeValue: { d in
                        d[HorizontalAlignment.trailing]
                    })
                    .padding()
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
                    .background(.orange)
                
                Text("VStack 3")
                    .padding()
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
                    .background(.pink)

                Text("VStack 4")
                    .padding()
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
                    .background(.green)
            }
            
            // Overlay
            VStack {
                Text("Item 1")
                Text("Item 2")
                Text("Item 3")
                Text("Item 4")
                Text("Item 5")
            }
            .padding()
            .background(.gray)
            // alignment of overlay
            .alignmentGuide(.myVerticalAlignment, computeValue: { d in
                d[VerticalAlignment.top]
            })
            .alignmentGuide(.myHorizontalAlignment, computeValue: { d in
                d[HorizontalAlignment.leading]
            })
        }
    }
}


extension VerticalAlignment {
    private enum MyVerticalAlignment : AlignmentID {
        static func defaultValue(in d: ViewDimensions) -> CGFloat {
            return d[.bottom]
        }
    }
    
    static let myVerticalAlignment = VerticalAlignment(MyVerticalAlignment.self)
}

extension HorizontalAlignment {
    private enum MyHorizontalAlignment : AlignmentID {
        static func defaultValue(in d: ViewDimensions) -> CGFloat {
            return d[.leading]
        }
    }
    
    static let myHorizontalAlignment = HorizontalAlignment(MyHorizontalAlignment.self)
}

extension Alignment {
    static let myAlignment = Alignment(horizontal: .myHorizontalAlignment, vertical: .myVerticalAlignment)
}
   

But a much easier way for a dropdown menu would be using either .contextMenu (appearing on long press)

                Text("VStack 1 - press long")
                // option 1
                    .contextMenu {
                        Button("Item 1") {}
                        Button("Item 2") {}
                        Button("Item 3") {}
                    }

or a Menu style picker:

               HStack {
                    Text("VStack 3")
                    // option 2
                    Picker("Menu", selection: $selection) {
                        Text("Item 1")
                        Text("Item 2")
                        Text("Item 3")
                    }
                    .pickerStyle(.menu)
                }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM