Suchleiste mit Verlauf – Swift UI, SQLite

[ad_1]

SQLite wird verwendet, um die Daten lokal in der App in der SQL-Struktur zu speichern. Es ist eine relationale lokale Datenbank. Sie können diese Datenbank verwenden, um Daten in der App mithilfe von Swift und Swift UI zu speichern.

Wir werden eine einfache iOS-App in der Swift-Benutzeroberfläche erstellen, um Tiere aus einem Array zu suchen und die gesuchten Zeichenfolgen des Benutzers in der SQLite-Datenbank zu speichern.

Wir werden eine Bibliothek namens SQLite von verwenden Stephen Celis. Um diese Bibliothek zu installieren, müssen Cocoapods in Ihrem System installiert sein.

Sie können Cocoapods in Ihrem System installieren, indem Sie einfach den folgenden Befehl in Ihrem Terminal ausführen:

sudo gem install cocoapods

Zunächst müssen Sie eine Eingabeaufforderung (Terminal) im Stammverzeichnis Ihres XCode-Projekts öffnen und den folgenden Befehl ausführen:

pod init

Jetzt sehen Sie eine neue Datei, die im Stammverzeichnis Ihres Projekts mit dem Namen erstellt wurde Podfile. Öffnen Sie diese Datei in Ihrem Texteditor und fügen Sie die Zeile hinzu, um die Bibliothek zu installieren. Folgendes wird der Inhalt Ihres Podfiles sein:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
 
target 'SQLite_Database' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
 
  # Pods for SQLite_Database
  pod 'SQLite.swift', '~> 0.12.0'
 
end

Führen Sie danach den folgenden Befehl in Ihrem Terminal aus, um diese Bibliothek zu installieren:

pod update

Schließen Sie nach der Installation Ihren XCode und öffnen Sie ihn erneut. Doppelklicken Sie diesmal jedoch auf die Datei mit der Erweiterung „.xcworkspace“. Diese Datei wird erst erstellt, nachdem der Pod installiert / aktualisiert wurde.

Zuerst erstellen wir eine Suchleiste mit einem TextField. Wenn der Benutzer dann auf “Senden” klickt, senden wir den gesuchten Wert in der nächsten Ansicht.

In der zweiten Ansicht erhalten wir den Wert aus dem Textfeld der ersten Ansicht und suchen diesen Wert in einem Array. Zeigen Sie dann alle Datensätze an, die mit der gesuchten Zeichenfolge übereinstimmen, und zeigen Sie sie in der Listenansicht an.

Erstellen Sie Statusvariablen in Ihrer Inhaltsansicht:

// variable to goto search view
@State var gotoSearchPage: Bool = false

// value that is searched from the text field
@State var searchedText: String = ""

Im Folgenden wird der Inhalt des Inhalts Ihrer Inhaltsansicht aufgeführt:

// live tracking of input field value
let binding = Binding<String>(get: {
    self.searchedText
}, set: { (value) in
    self.searchedText = value
})

// navigation view to goto search view
return NavigationView {

    VStack (alignment: .leading, spacing: 10) {
    
        // navigation link to goto search view
        NavigationLink (destination: SearchView(searchedText: self.$searchedText), isActive: self.$gotoSearchPage) {
            EmptyView()
        }
    
        // search field
        TextField("Search ...", text: binding, onCommit: {
        
            // goto search view when search icon is clicked
            self.gotoSearchPage = true
        
        })
            .padding(7)
            .padding(.horizontal, 5)
            .background(Color(.systemGray6))
            .cornerRadius(8)
            .disableAutocorrection(true)
            .keyboardType(.webSearch)
        
    }
    .padding(20)
    .navigationBarTitle("Search - SQLite")
}

Dadurch wird ein Textfeld erstellt, in das Sie Ihre Abfrage eingeben können. Wenn Sie auf “Suchsymbol” klicken, gelangen Sie zur Suchansicht, die wir im nächsten Schritt erstellen.

content-view-search-bar-with-history-swift-ui-sqlite-adnantech.com

Jetzt müssen wir eine Suchansicht erstellen, in der wir die Suche durchführen und die gefilterten Datensätze in einer Listenansicht anzeigen.

Erstellen Sie eine modale Klasse für Animal:

//
//  Animal.swift
//  Search bar with history
//
//  Created by Adnan Afzal on 02/12/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import Foundation

class Animal: Identifiable {
    var id: Int64 = 0
    var name: String = ""
    
    init() {
        //
    }
    
    init(name: String) {
        self.name = name
    }
}

Erstellen Sie eine neue Datei mit dem Namen SearchView.swift und fügen Sie den folgenden Code ein:

//
//  SearchView.swift
//  Search bar with history
//
//  Created by Adnan Afzal on 02/12/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import SwiftUI

struct SearchView: View {
    
    // get searched value from the previous view
    @Binding var searchedText: String
    
    // a list of all items (change this variable as per your need)
    @State var animals: [Animal] = []
    
    // list of items that matched the searched text
    @State var searchedArray: [Animal] = []
    
    var body: some View {
        
        VStack {
            
            // show searched text
            Text("(searchedText)").bold()
            
            // show items that matched the searched text in list view
            List (self.searchedArray) { (item) in
                Button(action: {
                    //
                }, label: {
                    Text(item.name)
                })
            }
        }.onAppear(perform: {
        
            // make the items empty when the page loads
            self.animals.removeAll()
            
            // add the data that needs to be searched (you can put your own array items here)
            self.animals.append(Animal(name: "Lion"))
            self.animals.append(Animal(name: "Tiger"))
            self.animals.append(Animal(name: "Rhino"))
            self.animals.append(Animal(name: "Elephant"))
            self.animals.append(Animal(name: "Cheetah"))
            self.animals.append(Animal(name: "Polar bear"))
            self.animals.append(Animal(name: "Leopard"))
            self.animals.append(Animal(name: "Wolf"))
            
            // empty the searched array
            self.searchedArray.removeAll()
            
            // find all the elements that matched the searched string
            for animal in self.animals {
                if (animal.name.lowercased().contains(self.searchedText.lowercased())) {
                    self.searchedArray.append(animal)
                }
            }
        })
        
    }
}

struct SearchView_Previews: PreviewProvider {

    // when using @Binding, use this in preview provider
    @State static var searchedText: String = ""

    static var previews: some View {
        SearchView(searchedText: $searchedText)
    }
}

Zu jeder Zeile wurden Kommentare hinzugefügt, um jede Zeile einzeln zu erläutern. Jetzt können Sie die Suche durchführen und die Tiere sehen, die das Namensfeld enthalten, das mit dem in der ersten Ansicht eingegebenen Textfeldwert übereinstimmt.

search-view-search-bar-with-history-swift-ui-sqlite-adnantech.com

Jetzt müssen wir den Suchverlauf in der Inhaltsansicht anzeigen. Dazu müssen wir zuerst jede gesuchte Zeichenfolge in der SQLite-Datenbank speichern.

Erstellen Sie eine separate Klasse mit dem Namen „DB_Manager”, Das alle Funktionen für die SQLite-Datenbank enthält.

//
//  DB_Manager.swift
//  Search bar with history
//
//  Created by Adnan Afzal on 02/12/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import Foundation

// import library
import SQLite

class DB_Manager {

    // sqlite instance
    private var db: Connection!
     
    // table instance
    private var animals: Table!
 
    // columns instances of table
    private var id: Expression<Int64>!
    private var name: Expression<String>!
    
    // constructor of this class
    init () {
         
        // exception handling
        do {
             
            // path of document directory
            let path: String = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first ?? ""
 
            // creating database connection
            db = try Connection("(path)/my_animals.sqlite3")
             
            // creating table object
            animals = Table("animals")
             
            // create instances of each column
            id = Expression<Int64>("id")
            name = Expression<String>("name")
             
            // check if the animal's table is already created
            if (!UserDefaults.standard.bool(forKey: "is_db_created")) {
 
                // if not, then create the table
                try db.run(animals.create { 
                    t.column(id, primaryKey: true)
                    t.column(name)
                })
                 
                // set the value to true, so it will not attempt to create the table again
                UserDefaults.standard.set(true, forKey: "is_db_created")
            }
             
        } catch {
            // show error message if any
            print(error.localizedDescription)
        }
         
    }

    // check if record already exists in SQLite
    public func isExists(searchedText: String) -> Bool {
     
        var isExists: Bool = false
         
        // exception handling
        do {
     
            // get animal using ID
            let animal: AnySequence<Row> = try db.prepare(animals.filter(name.lowercaseString == searchedText.lowercased()))
     
            // get row
            animal.forEach({ (rowValue) in
                isExists = true
            })
            
        } catch {
            print(error.localizedDescription)
        }
     
        return isExists
    }
    
    // add a new row in SQLite
    public func addAnimal(nameValue: String) {
        do {
            try db.run(animals.insert(name <- nameValue))
        } catch {
            print(error.localizedDescription)
        }
    }
    
}

Zur Erläuterung wurden zu jeder Zeile Kommentare hinzugefügt. Nun, in Ihrer Suchansicht innerhalb der onAppear () Funktion, überprüfen Sie, ob die gesuchte Zeichenfolge bereits in der SQLite-Datenbank vorhanden ist. Wenn NICHT, fügen Sie den gesuchten Text in die SQLite-Datenbank ein.

// add the searched text in SQLite database if NOT exists
let isExists: Bool = DB_Manager().isExists(searchedText: self.searchedText)
if (!isExists) {
    DB_Manager().addAnimal(nameValue: self.searchedText)
}

Jetzt müssen wir den Suchverlauf in der Hauptinhaltsansicht anzeigen, wenn der Benutzer auf das Textfeld der Suchleiste klickt. Erstellen Sie also zwei Status-Wrapper-Eigenschaften in Ihrer Inhaltsansicht:

// variable to show search history view
@State var showSearchHistoryView: Bool = false

// array of history array
@State var history: [Animal] = []

Und im Körper müssen wir die Live-Textänderung des Eingabefeldes verfolgen. Wir haben bereits eine Bindungsvariable im Hauptteil der Inhaltsansicht erstellt. Ändern Sie die Bindungsvariable im Hauptteil der Inhaltsansicht wie folgt:

// live tracking of input field value
let binding = Binding<String>(get: {
    self.searchedText
}, set: { (value) in
    self.searchedText = value
    
    // show history if the text field is not empty
    self.showSearchHistoryView = !self.searchedText.isEmpty
})

Nun, wenn die showSearchHistoryView Variable ist wahr, wir müssen eine Liste aller zuvor gesuchten Zeichenfolgen anzeigen. Erstellen Sie also eine Listenansicht unter einem wenn Bedingung unterhalb des Textfelds der Suchleiste:

// show history view only when a variable is true
if (self.showSearchHistoryView) {
    
    // create list view to show all history items
    List (self.history) { (model) in
    
        // show history text
        HStack {
        
            Image(systemName: "arrow.counterclockwise")
        
            Button(action: {
                self.searchedText = model.name
                self.gotoSearchPage = true
            }, label: {
                Text(model.name)
            })

        }
    }
}

Daraufhin wird ein Symbol für die Gegenuhr angezeigt, das angibt, dass es sich um Daten aus dem Verlauf handelt. Diese Schaltfläche zeigt die zuvor gesuchte Zeichenfolge an und wechselt beim Klicken in die Suchansicht.

Jetzt müssen wir die Daten in unsere laden Geschichte Array. Fügen Sie also eine onAppear () Veranstaltung zu Ihrem VStack und holen Sie die Daten aus der SQLite-Datenbank und speichern Sie sie im Verlaufsarray.

// load data in history models array
.onAppear(perform: {
    self.history = DB_Manager().getAnimals()
})

Jetzt müssen wir eine Funktion mit dem Namen erstellen getAnimals () in unserer DB_Manager Klasse, die die Datensätze aus der SQLite-Datenbank abruft.

// return array of animal models
public func getAnimals() -> [Animal] {
     
    // create empty array
    var animalModels: [Animal] = []
 
    // get all animals in descending order
    animals = animals.order(id.desc)
 
    // exception handling
    do {
 
        // loop through all animals
        for animal in try db.prepare(animals) {
 
            // create new model in each loop iteration
            let animalModel: Animal = Animal()
 
            // set values in model from database
            animalModel.id = animal[id]
            animalModel.name = animal[name]
 
            // append in new array
            animalModels.append(animalModel)
        }
    } catch {
        print(error.localizedDescription)
    }
 
    // return array
    return animalModels
}

Zur Erläuterung wurden zu jeder Zeile Kommentare hinzugefügt. Wenn Sie den Code jetzt ausführen, können Sie alle gesuchten Zeichenfolgen in einer Listenansicht anzeigen. Wenn Sie darauf klicken, gelangen Sie zum Suchansichtsbildschirm.

search-history-search-bar-with-history-swift-ui-sqlite-adnantech.com

Jetzt benötigen wir eine Funktion, um die Zeichenfolge aus dem Suchverlauf zu löschen. Erstellen Sie zunächst eine Schaltfläche in Ihrer Verlaufsliste nach dem Gegenuhrsymbol und der Schaltfläche in Ihrer Inhaltsansicht:

... counter-clock icon and button

// show delete button
Spacer()
Button(action: {
    
    // delete history item from SQLite
    DB_Manager().deleteAnimal(idValue: model.id)
    
    // refresh the list view
    self.history = DB_Manager().getAnimals()
    
}, label: {
    Text("Delete")
        .foregroundColor(Color.red)
})// by default, buttons are full width.
// to prevent this, use the following
.buttonStyle(PlainButtonStyle())

Jetzt müssen wir eine Funktion mit dem Namen erstellen deleteAnimal () in unserer DB_Manager Klasse, die die Zeile aus der SQLite-Datenbank löscht.

// function to delete animal from search history
public func deleteAnimal(idValue: Int64) {
    do {
    
        // get animal using ID
        let animal: Table = animals.filter(id == idValue)
         
        // run the delete query
        try db.run(animal.delete())
        
    } catch {
        print(error.localizedDescription)
    }
}

Führen Sie den Code jetzt aus, und am Ende jeder Verlaufszeile wird eine Schaltfläche zum Löschen angezeigt. Beim Klicken wird die Zeile aus der SQLite-Datenbank und auch aus der Listenansicht entfernt.

Erstellen Sie eine Suchleiste mit Suchverlauf. swiftui-ios-adnantech.com



[ad_2]