Webentwicklung
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.
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.
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.
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.
Download-Link generieren
[ad_2]