ios 创建一个下拉列表而不影响HStack

mqxuamgl  于 2023-08-08  发布在  iOS
关注(0)|答案(2)|浏览(80)

我试着创建一个下拉列表,但是列表看起来不太好,当打开时,它一直在改变HStack的大小

ZStack {
                VStack() {
                    HStack(spacing: 0) {
                        HStack {
                            Text(filters[selectedFilter].name)
                                .foregroundColor(Color.black)
                                .font(.system(size: 25))
                            Image(systemName: "chevron.right")
                                .aspectRatio(contentMode: .fit)
                                .font(.system(size: 25, weight: .none))
                        }
                        .padding(10)
                        .background(.ultraThinMaterial, in : RoundedRectangle(cornerRadius: 45.0))
                        .onTapGesture {
                            withAnimation(Animation.spring().speed(2)) {
                                showOptions.toggle()
                            }
                        }
                        
                        if showOptions {
                            VStack() {
                                ForEach(filters.indices, id: \.self) { i in
                                    Text(filters[i].name)
                                        .onTapGesture {
                                            showOptions.toggle()
                                            selectedFilter = i
                                        }
                                }
                            }
                            .background(.ultraThinMaterial, in : RoundedRectangle(cornerRadius: 45.0))
                        }

字符串
我贴了一些崩溃时的照片


的数据
展开时低于



我不想在右边,但下面的下拉列表。正如你所看到的,整个图标都在向下移动。我需要的图标,留在顶部,只是有一个简单的下拉菜单时,在左边的文本点击
知道吗?谢谢

9gm1akwq

9gm1akwq1#

其他按钮向下移动,因为HStack的对齐方式是.center
如果将对齐设置为.top,则其他按钮不会向下移动:

@State var showingDropdown = false

var body: some View {
    VStack {
        HStack(alignment: .top) {
            (Text("Surf ") + Text(Image(systemName: "chevron.right")))
                .padding()
                .background(.thinMaterial)
                .cornerRadius(30)
                .onTapGesture {
                    withAnimation {
                        showingDropdown.toggle()
                    }
                }
            if showingDropdown {
                VStack(spacing: 5) {
                    ForEach(options, id: \.self) { option in
                        Text(option)
                    }
                }
                .padding()
                .background(.thinMaterial)
                .cornerRadius(30)
            }
        }
        .padding()
        Spacer()
    }
}

字符串
如果您希望下拉列表直接出现在“Surf >"下面,请将它们都 Package 在VStack(alignment: .leading)中。同样,这里的对齐很重要。
也就是说,创建下拉列表的更简单方法是使用Menu

let options = ["option1", "option2", "foo", "bar", "baz", "something else"]
Menu {
    ForEach(options, id: \.self) { option in
        Button(option) {
            // ...
        }
    }
} label: {
    (Text("Surf ") + Text(Image(systemName: "chevron.right")))
}
.padding()
.background(.thinMaterial)
.cornerRadius(30)

的数据
由于这看起来像一个选择器,因此也可以考虑使用Picker.menu样式:

@State var pickedOption = "option1"
Picker("Some Picker", selection: $pickedOption) {
    ForEach(options, id: \.self) { option in
        Text(option)
    }
}
.padding()
.background(.thinMaterial)
.cornerRadius(30)
.pickerStyle(.menu)

的字符串

djmepvbi

djmepvbi2#

首先创建一个自定义首选项。

struct BoundsPreferenceKey: PreferenceKey {
    static var defaultValue: [Anchor<CGRect>] = [] 
    
    static func reduce(value: inout [Anchor<CGRect>], nextValue: () -> [Anchor<CGRect>]) {
        value.append(contentsOf:nextValue())
    }
}

字符串
然后将锚点首选项键添加到所需的视图中。在当前情况下,Surf Button

(Text("Surf ") + Text(Image(systemName: "chevron.right")))
                .padding()
                .background(.thinMaterial)
                .cornerRadius(30)
                .anchorPreference(key: BoundsPreferenceKey.self, //anchor preference  
                                      value: .bounds) { [$0] }
                .onTapGesture {
                    withAnimation {
                        showingDropdown.toggle()
                    }
                }


最后将overlayPreferenceValue添加到VStack

VStack {
        HStack(alignment: .top) {
            (Text("Surf ") + Text(Image(systemName: "chevron.right")))
                .padding()
                .background(.thinMaterial)
                .cornerRadius(30)
                .onTapGesture {
                    withAnimation {
                        showingDropdown.toggle()
                    }
                }
           
        }
        .padding()
        Spacer()
    }
    .overlayPreferenceValue(BoundsPreferenceKey.self) { // Add this 
            pref in
            GeometryReader { geometry in
                if showingDropdown { // flag to make it conditional otherwise this will be visible 
                    pref.map{
                        
                        YourMenuView // Replace this with your view for the menu
                            .offset(x: geometry[$0].minX,
                                    y: geometry[$0].minY + (geometry[$0].height + 8)) // replace 8 with any number you want this will act as padding
                        
                    }[0]
                } else {
                    EmptyView()
                }
                
            }
    }


的数据

相关问题