What You Will Build

A custom dropdown selector that expands with spring animation, shows a scrollable list of options, and collapses on selection. This replaces Picker when you need full control over appearance.

The Complete Dropdown

struct AnimatedDropdown: View {
    @State private var isExpanded = false
    @State private var selected = "Select an option"
    let options = ["Swift", "Kotlin", "Dart", "TypeScript", "Rust"]

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            // Header
            HStack {
                Text(selected)
                    .foregroundStyle(selected == "Select an option" ? .gray : .primary)
                Spacer()
                Image(systemName: "chevron.down")
                    .rotationEffect(.degrees(isExpanded ? -180 : 0))
            }
            .padding()
            .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 12))
            .onTapGesture {
                withAnimation(.spring(duration: 0.3)) { isExpanded.toggle() }
            }

            // Options
            if isExpanded {
                VStack(alignment: .leading, spacing: 0) {
                    ForEach(options, id: \.self) { option in
                        Text(option)
                            .padding(.horizontal).padding(.vertical, 12)
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .background(selected == option ? Color.blue.opacity(0.1) : .clear)
                            .onTapGesture {
                                selected = option
                                withAnimation(.spring(duration: 0.3)) { isExpanded = false }
                            }
                        Divider()
                    }
                }
                .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 12))
                .transition(.opacity.combined(with: .move(edge: .top)))
            }
        }
        .zIndex(1)
        .padding()
    }
}

Tips

  • zIndex is critical so expanded options render above content below.
  • Chevron rotation gives clear open/close feedback.
  • Add outside-tap-to-close with a transparent overlay in production.

iOS Version: iOS 15+

Get New Tutorials by Email

No spam. Just clear, practical breakdowns you can apply right away.

Enjoy this tutorial?

Get new practical tech tutorials in your inbox.