有没有办法在SwiftUI中创建下拉菜单/按钮?

时间:2019-06-09 09:10:34

标签: ios xcode drop-down-menu swiftui

我想在Xcode 11 Beta 1中创建一个下拉菜单。但是我还没有在iOS中找到一种方法。

我已经使用.hidden函数进行了尝试,找到了PullDownButton,但不知道如何设置

我已经创建了此代码

struct SwiftUIView : View {
@State var array = true
@State var buttonTitle = "Zeige Deteils"

var body: some View {
    VStack {
        VStack {
            Button(action: {
                self.array.toggle()

            }) {
                Text(buttonTitle)
            }


            if array {
                VStack(spacing: 1.0) {

                    Button(action: {
                        self.buttonTitle = "Schmelzpunkt"
                        self.array.toggle()
                    }) {
                        Text("Schmelzpunkt")
                            .color(.white)
                            .padding(.all)
                    }
                    .background(Color.blue)
                    Button(action: {
                        self.buttonTitle = "Instrumentelle Analytik"
                        self.array.toggle()
                    }) {
                        Text("Instrumentelle Analytik")
                            .color(.white)
                            .padding(.all)
                            }.background(Color.blue)
                            Button(action: {
                                self.buttonTitle = "Aussehen"
                                self.array.toggle()
                            }) {
                                Text("Aussehen")
                                    .color(.white)
                                    .padding(.all)
                                    }.background(Color.blue)

                                }
                                .padding(.top)
                        }
                    }
                }
}

但是找不到一个是为隐藏的Buttons的“弹出”动画,并希望主按钮保持其位置

6 个答案:

答案 0 :(得分:3)

在SwiftUI 2.0(iOS 14+)中,您可以使用Menu进行下拉菜单。

Menu {
    Button {
        style = 0
    } label: {
        Text("Linear")
        Image(systemName: "arrow.down.right.circle")
    }
    Button {
        style = 1
    } label: {
        Text("Radial")
        Image(systemName: "arrow.up.and.down.circle")
    }
} label: {
     Text("Style")
     Image(systemName: "tag.circle")
}

答案 1 :(得分:2)

您需要使用覆盖显示下拉列表。否则,当您显示和隐藏下拉菜单时,父母的布局将是错误的。

demo

这是一个简单的答案,完整的答案可以找到here

struct Dropdown: View {
    var options: [DropdownOption]
    var onSelect: ((_ key: String) -> Void)?

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            ForEach(self.options, id: \.self) { option in
                DropdownOptionElement(val: option.val, key: option.key, onSelect: self.onSelect)
            }
        }

        .background(Color.white)
        .cornerRadius(dropdownCornerRadius)
        .overlay(
            RoundedRectangle(cornerRadius: dropdownCornerRadius)
                .stroke(Color.coreUIPrimary, lineWidth: 1)
        )
    }
}

struct DropdownButton: View {
    @State var shouldShowDropdown = false
    @Binding var displayText: String
    var options: [DropdownOption]
    var onSelect: ((_ key: String) -> Void)?

    let buttonHeight: CGFloat = 30
    var body: some View {
        Button(action: {
            self.shouldShowDropdown.toggle()
        }) {
            HStack {
                Text(displayText)
                Spacer()
                    .frame(width: 20)
                Image(systemName: self.shouldShowDropdown ? "chevron.up" : "chevron.down")
            }
        }
        .padding(.horizontal)
        .cornerRadius(dropdownCornerRadius)
        .frame(height: self.buttonHeight)
        .overlay(
            RoundedRectangle(cornerRadius: dropdownCornerRadius)
                .stroke(Color.coreUIPrimary, lineWidth: 1)
        )
        .overlay(
            VStack {
                if self.shouldShowDropdown {
                    Spacer(minLength: buttonHeight + 10)
                    Dropdown(options: self.options, onSelect: self.onSelect)
                }
            }, alignment: .topLeading
        )
        .background(
            RoundedRectangle(cornerRadius: dropdownCornerRadius).fill(Color.white)
        )
    }
}

答案 2 :(得分:2)

使用Command PhaseScriptExecution failed with a nonzero exit code,您还可以使用SwiftUI 2.0来实现下拉菜单。

DisclosureGroup

答案 3 :(得分:0)

您可能想看看Picker

struct ContentView : View {
    @State private var selection = 1
    var body: some View {
        VStack {
            Picker(selection: $selection, label: Text("Zeige Deteils")) {
                Text("Schmelzpunkt").tag(1)
                Text("Instrumentelle Analytik").tag(2)
            }
        }
    }
}

enter image description here

答案 4 :(得分:0)

           Text("Options")
            .contextMenu {
                Button(action: {
                    // change country setting
                }) {
                    Text("Choose Country")
                }

                Button(action: {
                    // enable geolocation
                }) {
                    Text("Detect Location")
                }
            }

取自https://www.hackingwithswift.com/quick-start/swiftui/how-to-show-a-context-menu 右键单击以显示视图

答案 5 :(得分:0)

很多不错的答案,但对我有用的是一些自定义但与swiftui

中的Menu非常相似的东西

因此,首先为下拉视图创建您的项目。

示例。

import SwiftUI


struct SampleDropDown: View {
    
  
    let action : (String?) -> Void
    
    var body: some View {
        
        
        VStack(alignment: .leading, spacing: 4){
            
            ForEach(0...3, id: \.self){ valueStore in
                
                Button(action: {
                    
                    
                    
                }) {
                    
                    HStack(alignment: .center, spacing: 8) {
                        
                        Image(systemName: "bell")
                            .resizable()
                            .frame(width: 30, height: 30, alignment: .center)
                            .clipShape(Circle())
                        
                        VStack (alignment: .leading){
                            Text("ANDROID" )
                                .font(.custom(Constants.FONT_REGULAR, size: 14))
                                .foregroundColor(Color.fromHex(Colors.TEXT_COLOR_PRIMARY))
                                .padding([.leading, .top], 4)
                            
                            Text("#jetpack")
                                .font(.custom(Constants.FONT_REGULAR, size: 12))
                                .foregroundColor(Color.fromHex(Colors.LIGHT_GREY))
                                .padding([.leading, .bottom], 2)
                            
                        }
                        
                        
                    }.foregroundColor(Color.fromHex(Colors.LIGHT_GREY))
                    
                }.frame(width: .none, height: .none, alignment: .center)
                
                
                Divider().background(Color.fromHex(Colors.DIVIDOR))
                
            }
            
        }.padding(.all, 12)
        .background(RoundedRectangle(cornerRadius: 6).foregroundColor(.white).shadow(radius: 2))
        
    }
}

struct SampleDropDown_Previews: PreviewProvider {

    static var previews: some View {
        SampleDropDown(action: {data in}).padding()
    }
}

到目前为止的用户界面:

enter image description here

现在只需将其添加为 Overlay 您想要显示的位置或您想要显示的顶部。

类似的东西。

示例。

 @State var showStoreDropDown: Bool = false
  //ui 
 HStack(alignment: .center, spacing: 16) {
                    
                    //here you UI goes 
                    
                }.overlay (
                    
                    VStack {
                        
                        if showTimeframeDropDown {
                            
                            Spacer(minLength: 40)
                            
                            SampleDropDown(action: { data in
                                
                            })
                            
                        }
                        
                    }, alignment: .topLeading
                    
                ).onTapGesture {
                    
                    showTimeframeDropDown.toggle()
                    
                }

结果:

enter image description here

注意:这只是我项目中的示例代码,请进行相应更改,但基本思想是将下拉视图作为宿主视图上的叠加 .