SwiftUI Search Bar Component

Search field with a Cancel button that slides in on focus.

swiftui toggle
Cancel

Install the free SwiftUI search bar

  1. Add SwiftKitUI.swift to your app once. It holds the tokens and motion curves.
  2. Copy SKSearchBar.swift below into your project. It needs nothing else.

Usage

Usage.swift
SKSearchBar(text: $query)
SKSearchBar(text: $query, placeholder: "Search components") { submit() }

Full source · 110 lines · MIT

SKSearchBar.swift
//
//  SKSearchBar.swift
//  Swift Kit UI
//
//  Requires: SwiftKitUI.swift
//
//  Search field with a Cancel button that slides in on focus.
//
//  Cancel is width-animated rather than inserted, so the field shrinks smoothly
//  instead of the button popping into existence and shoving it sideways.
//
//  Usage:
//      SKSearchBar(text: $query)
//      SKSearchBar(text: $query, placeholder: "Search components") { submit() }
//

import SwiftUI

public struct SKSearchBar: View {
    @Binding private var text: String
    private let placeholder: String
    private let onSubmit: (() -> Void)?

    @FocusState private var focused: Bool
    @Environment(\.accessibilityReduceMotion) private var reduceMotion

    public init(
        text: Binding<String>,
        placeholder: String = "Search",
        onSubmit: (() -> Void)? = nil
    ) {
        self._text = text
        self.placeholder = placeholder
        self.onSubmit = onSubmit
    }

    public var body: some View {
        HStack(spacing: SK.Space.sm) {
            field
            if focused {
                Button("Cancel") {
                    text = ""
                    focused = false
                    SK.Haptic.play(.light)
                }
                .font(SK.Type_.callout)
                .foregroundStyle(SK.Palette.accent)
                .transition(.move(edge: .trailing).combined(with: .opacity))
            }
        }
        .skAnimation(.snap, value: focused)
    }

    private var field: some View {
        HStack(spacing: SK.Space.sm) {
            Image(systemName: "magnifyingglass")
                .font(SK.Icon.symbol(SK.Icon.md))
                .foregroundStyle(focused ? SK.Palette.accent : SK.Palette.labelTertiary)

            TextField(placeholder, text: $text)
                .font(SK.Type_.body)
                .foregroundStyle(SK.Palette.label)
                .focused($focused)
                .autocorrectionDisabled()
                .skCapitalization(.never)
                .submitLabel(.search)
                .onSubmit { onSubmit?() }

            if !text.isEmpty {
                Button {
                    text = ""
                    SK.Haptic.play(.light)
                } label: {
                    Image(systemName: "xmark.circle.fill")
                        .font(SK.Icon.symbol(SK.Icon.md))
                        .foregroundStyle(SK.Palette.labelTertiary)
                }
                .buttonStyle(.plain)
                .transition(.opacity.combined(with: .scale(scale: 0.7)))
                .accessibilityLabel("Clear search")
            }
        }
        .padding(.horizontal, SK.Space.md)
        .frame(height: SK.Icon.hitTarget)
        .background(SK.Palette.fill, in: Capsule(style: .continuous))
        .overlay {
            Capsule(style: .continuous)
                .strokeBorder(SK.Palette.accent, lineWidth: focused ? SK.Stroke.thick : 0)
        }
        .contentShape(.capsule)
        .onTapGesture { focused = true }
    }
}

#Preview("SKSearchBar") {
    @Previewable @State var query = ""
    @Previewable @State var filled = "swiftui toggle"

    VStack(spacing: SK.Space.xl) {
        SKSearchBar(text: $query)
        SKSearchBar(text: $filled, placeholder: "Search components")
        Text("Tap a field to see Cancel slide in")
            .font(SK.Type_.caption)
            .foregroundStyle(SK.Palette.labelTertiary)
    }
    .padding(SK.Space.xl)
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(SK.Palette.surfaceSunken)
}

Questions

Is this SwiftUI search bar free for commercial apps?
Yes. Swift Kit UI is MIT licensed, so you can use it in personal and commercial apps with no payment or sign-up. Keep the licence notice with the code.
What does it depend on?
SKSearchBar.swift depends only on SwiftKitUI.swift, a single foundation file with the design tokens and motion curves. There are no third-party packages.
Which iOS versions does it support?
iOS 17 and later, plus macOS 14.

Related components

Building a whole app? The Swift Kit adds auth, payments and onboarding, ready to ship.