[SUI] 검색 바

발행: (2026년 2월 3일 오전 07:02 GMT+9)
4 min read
원문: Dev.to

Source: Dev.to

NavigationStacksearchable 수식어를 사용하여 검색 바를 포함할 수 있습니다.
그 시그니처는 다음과 같습니다:

searchable(
    text: Binding,
    tokens: Binding? = nil,
    suggestedTokens: [Token]? = nil,
    placement: SearchFieldPlacement = .automatic,
    prompt: String? = nil,
    token: () -> TokenView? = { nil }
)
  • text: 사용자가 입력한 텍스트.
  • tokens: 표시된 토큰을 추적합니다.
  • suggestedTokens: 제안된 토큰 목록.
  • placement: 바의 위치 (automatic, navigationBarDrawer, sidebar, toolbar 등).
  • prompt: 플레이스홀더.
  • token: 토큰을 표시하기 위한 뷰.

기본 사용법

struct Person: Identifiable {
    let id = UUID()
    let name: String
}

private let people: [Person] = [
    .init(name: "David Goyes"),
    .init(name: "Midoriya Izuku"),
    .init(name: "Tanjiro Kamado"),
    .init(name: "David Beckham"),
]

struct ContentView: View {
    @State private var searchText: String = ""

    private var filteredPeople: [Person] {
        if searchText.isEmpty {
            people
        } else {
            people.filter { $0.name.localizedStandardContains(searchText) }
        }
    }

    var body: some View {
        NavigationStack {
            List(filteredPeople) { person in
                Text(person.name)
            }
            .navigationTitle("Personas")
            .searchable(text: $searchText, prompt: "¿A quién busca?")
        }
    }
}

iOS 26에서는 기본적으로 바가 하단에 배치됩니다(toolbar와 동일). first responder가 되면 키보드 위에 나타납니다.

onChange로 목록 업데이트

필터링된 결과를 저장하고 싶다면, 수동으로 업데이트해야 합니다:

struct ContentView: View {
    @State private var searchText: String = ""
    @State private var filteredPeople: [Person] = []

    var body: some View {
        NavigationStack {
            List(filteredPeople) { person in
                Text(person.name)
            }
            .navigationTitle("Personas")
            .searchable(text: $searchText, prompt: "¿A quién busca?")
            .onChange(of: searchText, initial: true) {
                filterPeople()
            }
        }
    }

    private func filterPeople() {
        filteredPeople = searchText.isEmpty
            ? people
            : people.filter { $0.name.localizedStandardContains(searchText) }
    }
}

검색창 위치

  • automatic / toolbar: 하단 바에 항상 표시됩니다.
  • navigationBarDrawer: 리스트를 위로 스크롤하면 사라지고 아래로 스크롤하면 다시 나타납니다.

네비게이션 바에 항상 표시하려면:

struct ContentView: View {
    @State private var searchText: String = ""

    private var filteredPeople: [Person] {
        if searchText.isEmpty {
            people
        } else {
            people.filter { $0.name.localizedStandardContains(searchText) }
        }
    }

    var body: some View {
        NavigationStack {
            List(filteredPeople) { person in
                Text(person.name)
            }
            .navigationTitle("Personas")
            .searchable(
                text: $searchText,
                placement: .navigationBarDrawer(displayMode: .always),
                prompt: "¿A quién busca?"
            )
        }
    }
}

searchFocused를 사용한 프로그래밍 방식 포커스 제어

searchFocused(_:)@FocusState를 이용해 검색 바의 포커스를 제어할 수 있습니다:

struct ContentView: View {
    @State private var searchText: String = ""
    @FocusState private var isFocused: Bool   // <-- 바의 포커스

    private var filteredPeople: [Person] {
        if searchText.isEmpty {
            people
        } else {
            people.filter { $0.name.localizedStandardContains(searchText) }
        }
    }

    var body: some View {
        NavigationStack {
            List(filteredPeople) { person in
                Text(person.name)
            }
            .navigationTitle("Personas")
            .toolbar {
                ToolbarItem(placement: .topBarTrailing) {
                    Button("Buscar", systemImage: "magnifyingglass") {
                        isFocused = true               // 바에 포커스를 맞춤
                    }
                }
            }
            .searchable(
                text: $searchText,
                placement: .navigationBarDrawer(displayMode: .automatic),
                prompt: "¿A quién busca?"
            )
            .searchFocused($isFocused)               // 포커스 제어
        }
    }
}

toolbar에 있는 “Buscar” 버튼을 누르면 isFocusedtrue로 설정되어 키보드가 나타나고 커서가 검색 바에 위치합니다.

Back to Blog

관련 글

더 보기 »

[SUI] 라벨드 콘텐츠

LabeledContent https://developer.apple.com/documentation/swiftui/labeledcontent 은 레이블을 컨트롤에 부착하는 컨테이너입니다. 기본 사용법 swift struct C...

[SUI] 양식 (Form)

Form Form은 컨트롤을 그룹화하기 위한 컨테이너이며, 주로 특정 기능의 설정에 사용됩니다. 컨트롤을 List에 표시합니다.

[SUI] MultiDatePicker

MultiDatePicker 사용 MultiDatePicker는 SwiftUI에서 여러 날짜를 선택할 수 있게 합니다. Swift 초기화 메서드 MultiDatePicker.init(_:selection:in:) - titleKey: 레이블 키…