mirror of
https://github.com/Matte23/circolapp.git
synced 2025-12-06 07:29:10 +00:00
Add search bar iOS
This commit is contained in:
@@ -13,6 +13,8 @@
|
|||||||
954E68352574E3890034EBA8 /* iOSServerApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954E68342574E3890034EBA8 /* iOSServerApi.swift */; };
|
954E68352574E3890034EBA8 /* iOSServerApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954E68342574E3890034EBA8 /* iOSServerApi.swift */; };
|
||||||
954E683D2574ED9E0034EBA8 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954E683C2574ED9E0034EBA8 /* UserDefaultsExtensions.swift */; };
|
954E683D2574ED9E0034EBA8 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954E683C2574ED9E0034EBA8 /* UserDefaultsExtensions.swift */; };
|
||||||
9553DB09257173ED006AE167 /* iOSRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9553DB08257173ED006AE167 /* iOSRepository.swift */; };
|
9553DB09257173ED006AE167 /* iOSRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9553DB08257173ED006AE167 /* iOSRepository.swift */; };
|
||||||
|
955B7A0E257D098C0091B1F9 /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955B7A0D257D098C0091B1F9 /* SearchBar.swift */; };
|
||||||
|
955B7A10257D10A70091B1F9 /* ViewControllerResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955B7A0F257D10A70091B1F9 /* ViewControllerResolver.swift */; };
|
||||||
95906F48257508660060F5D0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 95906F47257506360060F5D0 /* Assets.xcassets */; };
|
95906F48257508660060F5D0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 95906F47257506360060F5D0 /* Assets.xcassets */; };
|
||||||
95906F4D257510370060F5D0 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 95906F4C257510370060F5D0 /* GoogleService-Info.plist */; };
|
95906F4D257510370060F5D0 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 95906F4C257510370060F5D0 /* GoogleService-Info.plist */; };
|
||||||
95BC3BF82572BCF900F24400 /* AttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95BC3BF72572BCF900F24400 /* AttachmentView.swift */; };
|
95BC3BF82572BCF900F24400 /* AttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95BC3BF72572BCF900F24400 /* AttachmentView.swift */; };
|
||||||
@@ -49,6 +51,8 @@
|
|||||||
954E68342574E3890034EBA8 /* iOSServerApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSServerApi.swift; sourceTree = "<group>"; };
|
954E68342574E3890034EBA8 /* iOSServerApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSServerApi.swift; sourceTree = "<group>"; };
|
||||||
954E683C2574ED9E0034EBA8 /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = "<group>"; };
|
954E683C2574ED9E0034EBA8 /* UserDefaultsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtensions.swift; sourceTree = "<group>"; };
|
||||||
9553DB08257173ED006AE167 /* iOSRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSRepository.swift; sourceTree = "<group>"; };
|
9553DB08257173ED006AE167 /* iOSRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSRepository.swift; sourceTree = "<group>"; };
|
||||||
|
955B7A0D257D098C0091B1F9 /* SearchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBar.swift; sourceTree = "<group>"; };
|
||||||
|
955B7A0F257D10A70091B1F9 /* ViewControllerResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerResolver.swift; sourceTree = "<group>"; };
|
||||||
95906F47257506360060F5D0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
95906F47257506360060F5D0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
95906F4C257510370060F5D0 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
95906F4C257510370060F5D0 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||||
959B531E25764726009AD895 /* circolapp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = circolapp.entitlements; sourceTree = "<group>"; };
|
959B531E25764726009AD895 /* circolapp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = circolapp.entitlements; sourceTree = "<group>"; };
|
||||||
@@ -100,6 +104,8 @@
|
|||||||
95CA31BF255C28C300AC095B /* CircularView.swift */,
|
95CA31BF255C28C300AC095B /* CircularView.swift */,
|
||||||
95BC3BF72572BCF900F24400 /* AttachmentView.swift */,
|
95BC3BF72572BCF900F24400 /* AttachmentView.swift */,
|
||||||
9512D3C0257AB4F60023C3A1 /* NewReminderView.swift */,
|
9512D3C0257AB4F60023C3A1 /* NewReminderView.swift */,
|
||||||
|
955B7A0D257D098C0091B1F9 /* SearchBar.swift */,
|
||||||
|
955B7A0F257D10A70091B1F9 /* ViewControllerResolver.swift */,
|
||||||
);
|
);
|
||||||
path = View;
|
path = View;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -278,11 +284,13 @@
|
|||||||
95CA31C0255C28C300AC095B /* CircularView.swift in Sources */,
|
95CA31C0255C28C300AC095B /* CircularView.swift in Sources */,
|
||||||
952DEDDF2576F8DC001DF85D /* SceneDelegate.swift in Sources */,
|
952DEDDF2576F8DC001DF85D /* SceneDelegate.swift in Sources */,
|
||||||
95CA31B2255C1EDE00AC095B /* ContentView.swift in Sources */,
|
95CA31B2255C1EDE00AC095B /* ContentView.swift in Sources */,
|
||||||
|
955B7A10257D10A70091B1F9 /* ViewControllerResolver.swift in Sources */,
|
||||||
954E68352574E3890034EBA8 /* iOSServerApi.swift in Sources */,
|
954E68352574E3890034EBA8 /* iOSServerApi.swift in Sources */,
|
||||||
95CA31B0255C1EDE00AC095B /* AppDelegate.swift in Sources */,
|
95CA31B0255C1EDE00AC095B /* AppDelegate.swift in Sources */,
|
||||||
95BC3BF82572BCF900F24400 /* AttachmentView.swift in Sources */,
|
95BC3BF82572BCF900F24400 /* AttachmentView.swift in Sources */,
|
||||||
9512D3C1257AB4F60023C3A1 /* NewReminderView.swift in Sources */,
|
9512D3C1257AB4F60023C3A1 /* NewReminderView.swift in Sources */,
|
||||||
954E683D2574ED9E0034EBA8 /* UserDefaultsExtensions.swift in Sources */,
|
954E683D2574ED9E0034EBA8 /* UserDefaultsExtensions.swift in Sources */,
|
||||||
|
955B7A0E257D098C0091B1F9 /* SearchBar.swift in Sources */,
|
||||||
95C46A51255D3A34007A75E5 /* CircularViewModel.swift in Sources */,
|
95C46A51255D3A34007A75E5 /* CircularViewModel.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class CircularViewModel: ObservableObject {
|
|||||||
private var circularWatcher: Ktor_ioCloseable? = nil
|
private var circularWatcher: Ktor_ioCloseable? = nil
|
||||||
private var userDefaultsObserver: NSKeyValueObservation? = nil
|
private var userDefaultsObserver: NSKeyValueObservation? = nil
|
||||||
private var schoolID = 0
|
private var schoolID = 0
|
||||||
|
private var category: Category = .all
|
||||||
|
|
||||||
private let repository: CircularRepository
|
private let repository: CircularRepository
|
||||||
private let key = "school"
|
private let key = "school"
|
||||||
@@ -58,6 +59,7 @@ class CircularViewModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func startObservingCirculars() {
|
func startObservingCirculars() {
|
||||||
|
category = .all
|
||||||
stopObserving()
|
stopObserving()
|
||||||
circularWatcher = repository.circularDao.getCFlowCirculars(school: Int32(schoolID)).watch { circulars in
|
circularWatcher = repository.circularDao.getCFlowCirculars(school: Int32(schoolID)).watch { circulars in
|
||||||
self.circulars = circulars as! Array<Circular>;
|
self.circulars = circulars as! Array<Circular>;
|
||||||
@@ -65,13 +67,15 @@ class CircularViewModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func startObservingFavourites() {
|
func startObservingFavourites() {
|
||||||
|
category = .favourites
|
||||||
stopObserving()
|
stopObserving()
|
||||||
circularWatcher = repository.circularDao.getFavouritesC(school: Int32(schoolID)).watch { circulars in
|
circularWatcher = repository.circularDao.getFavouritesC(school: Int32(schoolID)).watch { circulars in
|
||||||
self.circulars = circulars as! Array<Circular>;
|
self.circulars = circulars as! Array<Circular>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func startObservingAlarms() {
|
func startObservingReminders() {
|
||||||
|
category = .reminders
|
||||||
stopObserving()
|
stopObserving()
|
||||||
circularWatcher = repository.circularDao.getCFlowReminders(school: Int32(schoolID)).watch { circulars in
|
circularWatcher = repository.circularDao.getCFlowReminders(school: Int32(schoolID)).watch { circulars in
|
||||||
self.circulars = circulars as! Array<Circular>;
|
self.circulars = circulars as! Array<Circular>;
|
||||||
@@ -81,4 +85,28 @@ class CircularViewModel: ObservableObject {
|
|||||||
func stopObserving() {
|
func stopObserving() {
|
||||||
circularWatcher?.close()
|
circularWatcher?.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func search(query: String) {
|
||||||
|
let wrappedQuery = "%" + query + "%"
|
||||||
|
|
||||||
|
stopObserving()
|
||||||
|
switch category {
|
||||||
|
case .all:
|
||||||
|
circularWatcher = repository.circularDao.searchCircularsC(query: wrappedQuery, school: Int32(schoolID)).watch { circulars in
|
||||||
|
self.circulars = circulars as! Array<Circular>;
|
||||||
|
}
|
||||||
|
case .favourites:
|
||||||
|
circularWatcher = repository.circularDao.searchFavouritesC(query: wrappedQuery, school: Int32(schoolID)).watch { circulars in
|
||||||
|
self.circulars = circulars as! Array<Circular>;
|
||||||
|
}
|
||||||
|
case .reminders:
|
||||||
|
circularWatcher = repository.circularDao.searchRemindersC(query: wrappedQuery, school: Int32(schoolID)).watch { circulars in
|
||||||
|
self.circulars = circulars as! Array<Circular>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Category {
|
||||||
|
case all, favourites, reminders
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import Shared
|
|||||||
|
|
||||||
struct ContentView: View {
|
struct ContentView: View {
|
||||||
@ObservedObject var circularViewModel = CircularViewModel(repository: iOSRepository.getCircularRepository())
|
@ObservedObject var circularViewModel = CircularViewModel(repository: iOSRepository.getCircularRepository())
|
||||||
|
@ObservedObject var searchBar: SearchBar = SearchBar(placeholder: "Search circulars")
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
@@ -29,6 +30,10 @@ struct ContentView: View {
|
|||||||
CircularView(circular: circular)
|
CircularView(circular: circular)
|
||||||
}
|
}
|
||||||
.navigationBarTitle(Text("Circulars"), displayMode: .large)
|
.navigationBarTitle(Text("Circulars"), displayMode: .large)
|
||||||
|
.addSearchBar(self.searchBar)
|
||||||
|
.onReceive(searchBar.$text) {query in
|
||||||
|
self.circularViewModel.search(query: query)
|
||||||
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
self.circularViewModel.startObservingCirculars()
|
self.circularViewModel.startObservingCirculars()
|
||||||
}
|
}
|
||||||
@@ -52,7 +57,7 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Button(action: {
|
Button(action: {
|
||||||
self.circularViewModel.startObservingAlarms()
|
self.circularViewModel.startObservingReminders()
|
||||||
}) {
|
}) {
|
||||||
Image(systemName: "alarm")
|
Image(systemName: "alarm")
|
||||||
}
|
}
|
||||||
|
|||||||
48
ios/circolapp/circolapp/View/SearchBar.swift
Normal file
48
ios/circolapp/circolapp/View/SearchBar.swift
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import UIKit
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
class SearchBar: NSObject, ObservableObject {
|
||||||
|
|
||||||
|
@Published var text: String = ""
|
||||||
|
let searchController: UISearchController = UISearchController(searchResultsController: nil)
|
||||||
|
|
||||||
|
init(placeholder: String) {
|
||||||
|
super.init()
|
||||||
|
self.searchController.obscuresBackgroundDuringPresentation = false
|
||||||
|
self.searchController.searchResultsUpdater = self
|
||||||
|
|
||||||
|
self.searchController.searchBar.placeholder = placeholder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SearchBar: UISearchResultsUpdating {
|
||||||
|
|
||||||
|
func updateSearchResults(for searchController: UISearchController) {
|
||||||
|
|
||||||
|
// Publish search bar text changes.
|
||||||
|
if let searchBarText = searchController.searchBar.text {
|
||||||
|
self.text = searchBarText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SearchBarModifier: ViewModifier {
|
||||||
|
|
||||||
|
let searchBar: SearchBar
|
||||||
|
|
||||||
|
func body(content: Content) -> some View {
|
||||||
|
content
|
||||||
|
.overlay(
|
||||||
|
ViewControllerResolver { viewController in
|
||||||
|
viewController.navigationItem.searchController = self.searchBar.searchController
|
||||||
|
}
|
||||||
|
.frame(width: 0, height: 0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension View {
|
||||||
|
func addSearchBar(_ searchBar: SearchBar) -> some View {
|
||||||
|
return self.modifier(SearchBarModifier(searchBar: searchBar))
|
||||||
|
}
|
||||||
|
}
|
||||||
39
ios/circolapp/circolapp/View/ViewControllerResolver.swift
Normal file
39
ios/circolapp/circolapp/View/ViewControllerResolver.swift
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
final class ViewControllerResolver: UIViewControllerRepresentable {
|
||||||
|
|
||||||
|
let onResolve: (UIViewController) -> Void
|
||||||
|
|
||||||
|
init(onResolve: @escaping (UIViewController) -> Void) {
|
||||||
|
self.onResolve = onResolve
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeUIViewController(context: Context) -> ParentResolverViewController {
|
||||||
|
ParentResolverViewController(onResolve: onResolve)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIViewController(_ uiViewController: ParentResolverViewController, context: Context) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
class ParentResolverViewController: UIViewController {
|
||||||
|
|
||||||
|
let onResolve: (UIViewController) -> Void
|
||||||
|
|
||||||
|
init(onResolve: @escaping (UIViewController) -> Void) {
|
||||||
|
self.onResolve = onResolve
|
||||||
|
super.init(nibName: nil, bundle: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("Use init(onResolve:) to instantiate ParentResolverViewController.")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func didMove(toParent parent: UIViewController?) {
|
||||||
|
super.didMove(toParent: parent)
|
||||||
|
|
||||||
|
if let parent = parent {
|
||||||
|
onResolve(parent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user