it-notepad.com

Глава 9. Добавление Search Bar SwiftUI

Оглавление

Введение

Добавляем Search Bar к компоненту ListView

Меняем текст подсказки в Search Bar

Делаем Search Bar видимым изначально

Добавление подсказок в Search Bar

Заключение

Введение

Когда Вы открываете приложение контакты на своем iPhone, вы видите список контактов, который вы сохранили. Если Вы хотите найти человека, вы должны либо вручную посмотреть все контакты, либо ввести данные этого человека в специальной области приложения(рис 9-1). В большинстве случаев это будет гораздо быстрее, чем ручной просмотр огромного списка контактов.

Рис 9-1 Search Bar в приложении Контакты

Начиная с версии iOs 15, XCode и Swift предоставляет функционал по созданию реализации Search Bar с поиском по данным, сохраненным в виджете List. По сути все что Вам нужно – сохранить данные в виджете View и затем добавить модификатор .searchable к этому виджету. Это добавит возможность осуществлять поиск в Вашем List.

Важное замечание – Search Bar работает только на устройствах под управлением iOs 15 и выше

Добавляем Search Bar к компоненту ListView

SwiftUI прикрепляет Search Bar к верхней границе элемента List. Для создания Search Bar, Вам необходимо создать NavigationView и затем к нему добавить модификатор .searchable:

NavigationView{

}.searchable(text: $stateVariable)

Как мы видим из кода свыше, нам обязательно нужна State переменная для использования с модификатором .searchable:

$State var stateVariable = ""

Поисковый ввод в Search Bar сохраняется в State переменной. И затем Вы должны отфильтровывать данные в элементе List  в соответствии с поисковым запросом, вот как это делается:

.searchable(text: $stateVariable){
    ForEach(listArray.filter{$0.hasPrefix(stateVariable)}, id: \.self) { name in Text(name)
}

Этот код предполагает  наличие массива данных listArray. Затем в цикле ForEach используется функция .filter для поиска введеного пользователем текста в поисковый виджет(stateVariable). Этот фильтр отображает теперь в элементе List только те элементы List, которые совпадают с поисковым запросом и выводит результат поиска в отдельном виджете Text.

Для того, чтобы посмотреть на практике, как организовать поиск в List, сделаем следующее:

  1. Создадим новое iOs приложение и назовем его Chapter9SearchApp.
  2. Откроем исходный файл ContentView
  3. Добавим State переменную для хранения введенного текста и массив для хранения данных List сразу под объявлением struct ContentView: View {
    @State var searchText = ""
    let petArray = ["Cat","Dog","Fish","Donkey","Canary","Camel","Frog"]

    Этот код создает State переменную для работы с поисковым виджетом. А также он создает массив элементов типа String. Обратите внимание, что каждая строка начинается с заглавной буквы. Это сделано потому что по умолчанию search bar всегда отображает первый введеный символ с прописной буквы.

  4. Создадим отдельную структуру для отображения виджета List
    struct PetListView: View{
        let animals: [String]
        var body: some View {
            List(animals, id: \.self){
                x in Text(x)
            }
        }
    }
  5. Изменим тело структуры ContentView
    NavigationView{
        PetListView(animals: petArray)
    }.searchable(text: $searchText){
        ForEach(petArray.filter {$0.hasPrefix(searchText)}, id: \.self) {
            name in Text(name)
        }
    }

    Этот код создает NavigationView, который отображает виджет List, определенный в структуре PetListView. Модификатор .searchable использует State переменную searchText для хранения любых введеных значений в панель поиска. Когда пользователь вводит текст в Search Bar, модификатор .searchable запускает цикл ForEach для поиска совпадений среди данных виджета List.

    Итоговый исходный код представлен ниже:

    //
    //  ContentView.swift
    //  Chapter9SearchApp
    //
    //  Created by Timur on 10.04.2023.
    //
    
    import SwiftUI
    
    struct ContentView: View {
        
        @State var searchText = ""
        let petArray = ["Cat","Dog","Fish","Donkey","Canary","Camel","Frog"]
        
        var body: some View {
            NavigationView{
                PetListView(animals: petArray)
            }.searchable(text: $searchText){
                ForEach(petArray.filter {$0.hasPrefix(searchText)}, id: \.self) {
                    name in Text(name)
                }
            }
        }
    }
    
    struct PetListView: View{
        let animals: [String]
        var body: some View {
            List(animals, id: \.self){
                x in Text(x)
            }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    

     

  6. Запустим предпросмотр на панели Canvas. Панель Canvas отобразит View виджет List, содержащий все элементы массива petArray
  7. Введем в панели поиска английскую букву C. Теперь вы увидите в view List только те значения, которые содержат букву “C”, как показано на рисунке 9-2

    Рис 9-2 Отображение элементов списка, удовлетворяющих параметрам поиска

  8. Продолжим вводить Can. Список отобразит только те варианты, которые удовлетворяют запросу “Can” – в данном случае это Canary.

По умолчанию, панель поиска отображает “Search”(“Поиск” в локализации) как текст подсказки, когда Search Bar видим и пользователь еще ничего не ввел(см. рисунок 9-1). Мы можем поставить себе цель, в том, чтобы изменить текст – подсказку на Ваш собственный вариант.

Для того, чтобы определить текст подсказки в панели поиска, просто добавьте текст после параметра promt:в модификаторе .searchable:

.searchable(text: $searchText, prompt: "Look for a pet")

Для того, чтобы изменить текст подсказки в панели поиска, сделаем следующее:

  1. Откроем проект Chapter9SearchApp в среде XCode
  2. Откроем файл ContentView в панели Навигатор.
  3. Подправим модификатор .searchable:
    .searchable(text: $searchText, prompt: "Look for a pet")
  4. Нажмем на иконку Preview в панели Canvas
  5. Мы обнаружим измененный макета предпросмотра – изменился текст подсказки, который мы указали с модификаторе .searchable, как видно на рисунке 9-3

    Рисунок 9-3 Изменение текста подсказки в панели поиска Search Bar

Делаем Search Bar видимым изначально

В версиях iOs до 16, по умолчанию модификатор .searchable не отображает панель поиска, пока пользователь не потянет List вниз. Это может привезти к непониманию пользователем структуры и возможностей UI, так как зачастую пользователи не хотят исследовать возможности Вашего приложения или смотреть презентацию того, что именно делает Ваша программа. Поэтому лучшим решением будет сделать панель поиска изначально видимой.

Для того, чтобы сделать Search Bar изначально видимым, необходимо всего лишь добавить один параметр к модификатору .searchable.navigationBarDrawer

.searchable(text: $searchText,  placement: .navigationBarDrawer(displayMode: .always), prompt: "Look for a pet")

Мы не будем приводить заново полный исходный код нашего проекта или пошагово писать что необходимо сделать. А только разместим внизу исходный код тела структуры ContentView

var body: some View {
    NavigationView{
        PetListView(animals: petArray)
    }.searchable(text: $searchText,  placement: .navigationBarDrawer(displayMode: .always), prompt: "Look for a pet"){
        ForEach(petArray.filter {$0.hasPrefix(searchText)}, id: \.self) {
           name in Text(name)
        }
    }
}

 

Добавление подсказок в Search Bar

Довольно часто панель поиска приложения отображает лист с часто используемыми или недавними поисковыми запросами. Что то подобное Вы можете видеть в панели поиска приложения YouTube. Если Вы хотите добавить функционал с автоматически предлагаемыми вариантами или подсказками – как мы это будем писать далее, необходимо добавить один или несколько элементов Text, отображающих список предлагаемых вариантов поиска. Для использования этого функционала, необходимо всего лишь добавить модификатор .searchCompletionк элементу Text:

Text("Croaking").searchCompletion("Frog")

Модификатор .searchCompletion содержит текст, который появляется в панели поиска, если пользователь выберет предложенный текст(отображаемый в виджете Text). В приведенном примере, “Croaking” появляется под строкой поиска и если пользователь выберет элемент “Croaking“, то .searchCompletion отобразит “Frog”  в панели поиска.

Для того, что добавить подсказки в панель поиска и посмотреть как это делается на практике, сделаем следующее:

  1. Убедимся что проект Chapter9SearchApp открыт в среде Xcode.
  2. Откроем нашу UI структуру ContentView
  3. Изменим модификатор .searchable следующим образом:
    .searchable(text: $searchText,  placement: .navigationBarDrawer(displayMode: .always), prompt: "Look for a pet"){
         Text("Singing").searchCompletion("Canary")
         Text("Croaking").searchCompletion("Frog")
         Text("Grumpy").searchCompletion("Cat")
         Divider()
         ForEach(petArray.filter {$0.hasPrefix(searchText)}, id: \.self) {
              name in Text(name)
         }
    }

    Итоговый код структуры ContentView

    struct ContentView: View {
        
        @State var searchText = ""
        let petArray = ["Cat","Dog","Fish","Donkey","Canary","Camel","Frog"]
        
        var body: some View {
            NavigationView{
                PetListView(animals: petArray)
            }.searchable(text: $searchText,  placement: .navigationBarDrawer(displayMode: .always), prompt: "Look for a pet"){
                Text("Singing").searchCompletion("Canary")
                Text("Croaking").searchCompletion("Frog")
                Text("Grumpy").searchCompletion("Cat")
                Divider()
                ForEach(petArray.filter {$0.hasPrefix(searchText)}, id: \.self) {
                    name in Text(name)
                }
            }
        }
    }

    Также обратите внимание, мы добавили разделитель между элементами подсказок и кодом цикла поиска для улучшения внешнего вида нашего приложения.

  4. Перейдем к окну предпросмотра
  5. Нажмем на панели поиска. Теперь Search Bar отображает поисковые подсказки с синим цветом шрифта(рис 9-4)

    Рис 9-4 Отображение списка подсказок в панели поиска

  6. Попробуем выбрать предлагаемый текст – в нашем случае это пусть будет “Grumpy”. После его выбора в панели поиска появится текст – Cat. Постарайтесь запомнить, что выбираемый текст, определяемый в модификаторе .searchCompletion элемента Text это и есть поисковый запрос.

Заключение

Search Bar – она же панель поиска нужна в вашем UI в том случае, если вы используете список с большим количеством элементов, не помещающимися на экране. Для того чтобы пользователь вместо утомительного скроллинга мог за пару мгновений найти интересующий его элемент.  Вы можете сделать элемент поиска как видимым сразу при открытии экрана, так и сделать его невидимым – открывающимся только при скроллинге элемента List вниз.

Создание списка подсказок может быть полезным для упрощения поиска. Виджеты Text вкупе с модификатором .searchCompletion создадут подсказки в Вашей панели. Если Вы подумали, как использовать подсказки динамически – значит Вы думаете в правильном направлении. Используя переменные, Вы можете динамически менять подсказки. На нашем сайте it-notepad.com мы обязательно выложим еще много переводов и статей по поиску, следите внимательно за обновлениями.

Необходимо помнить также о том, что Search Bar работает только доля версий iOs выше 15. Панель поиска предназначена для легкого и быстрого поиска элементов в списке List – так что обязательно предусматривайте такой функционал всякий раз, когда в этом есть необходимость.

Exit mobile version