mirror of
https://github.com/Matte23/circolapp.git
synced 2025-12-05 23:19: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 */; };
|
||||
954E683D2574ED9E0034EBA8 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 954E683C2574ED9E0034EBA8 /* UserDefaultsExtensions.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 */; };
|
||||
95906F4D257510370060F5D0 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 95906F4C257510370060F5D0 /* GoogleService-Info.plist */; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@@ -100,6 +104,8 @@
|
||||
95CA31BF255C28C300AC095B /* CircularView.swift */,
|
||||
95BC3BF72572BCF900F24400 /* AttachmentView.swift */,
|
||||
9512D3C0257AB4F60023C3A1 /* NewReminderView.swift */,
|
||||
955B7A0D257D098C0091B1F9 /* SearchBar.swift */,
|
||||
955B7A0F257D10A70091B1F9 /* ViewControllerResolver.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
@@ -278,11 +284,13 @@
|
||||
95CA31C0255C28C300AC095B /* CircularView.swift in Sources */,
|
||||
952DEDDF2576F8DC001DF85D /* SceneDelegate.swift in Sources */,
|
||||
95CA31B2255C1EDE00AC095B /* ContentView.swift in Sources */,
|
||||
955B7A10257D10A70091B1F9 /* ViewControllerResolver.swift in Sources */,
|
||||
954E68352574E3890034EBA8 /* iOSServerApi.swift in Sources */,
|
||||
95CA31B0255C1EDE00AC095B /* AppDelegate.swift in Sources */,
|
||||
95BC3BF82572BCF900F24400 /* AttachmentView.swift in Sources */,
|
||||
9512D3C1257AB4F60023C3A1 /* NewReminderView.swift in Sources */,
|
||||
954E683D2574ED9E0034EBA8 /* UserDefaultsExtensions.swift in Sources */,
|
||||
955B7A0E257D098C0091B1F9 /* SearchBar.swift in Sources */,
|
||||
95C46A51255D3A34007A75E5 /* CircularViewModel.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
||||
@@ -25,6 +25,7 @@ class CircularViewModel: ObservableObject {
|
||||
private var circularWatcher: Ktor_ioCloseable? = nil
|
||||
private var userDefaultsObserver: NSKeyValueObservation? = nil
|
||||
private var schoolID = 0
|
||||
private var category: Category = .all
|
||||
|
||||
private let repository: CircularRepository
|
||||
private let key = "school"
|
||||
@@ -58,6 +59,7 @@ class CircularViewModel: ObservableObject {
|
||||
}
|
||||
|
||||
func startObservingCirculars() {
|
||||
category = .all
|
||||
stopObserving()
|
||||
circularWatcher = repository.circularDao.getCFlowCirculars(school: Int32(schoolID)).watch { circulars in
|
||||
self.circulars = circulars as! Array<Circular>;
|
||||
@@ -65,13 +67,15 @@ class CircularViewModel: ObservableObject {
|
||||
}
|
||||
|
||||
func startObservingFavourites() {
|
||||
category = .favourites
|
||||
stopObserving()
|
||||
circularWatcher = repository.circularDao.getFavouritesC(school: Int32(schoolID)).watch { circulars in
|
||||
self.circulars = circulars as! Array<Circular>;
|
||||
}
|
||||
}
|
||||
|
||||
func startObservingAlarms() {
|
||||
func startObservingReminders() {
|
||||
category = .reminders
|
||||
stopObserving()
|
||||
circularWatcher = repository.circularDao.getCFlowReminders(school: Int32(schoolID)).watch { circulars in
|
||||
self.circulars = circulars as! Array<Circular>;
|
||||
@@ -81,4 +85,28 @@ class CircularViewModel: ObservableObject {
|
||||
func stopObserving() {
|
||||
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 {
|
||||
@ObservedObject var circularViewModel = CircularViewModel(repository: iOSRepository.getCircularRepository())
|
||||
@ObservedObject var searchBar: SearchBar = SearchBar(placeholder: "Search circulars")
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
@@ -29,6 +30,10 @@ struct ContentView: View {
|
||||
CircularView(circular: circular)
|
||||
}
|
||||
.navigationBarTitle(Text("Circulars"), displayMode: .large)
|
||||
.addSearchBar(self.searchBar)
|
||||
.onReceive(searchBar.$text) {query in
|
||||
self.circularViewModel.search(query: query)
|
||||
}
|
||||
.onAppear {
|
||||
self.circularViewModel.startObservingCirculars()
|
||||
}
|
||||
@@ -52,7 +57,7 @@ struct ContentView: View {
|
||||
}
|
||||
|
||||
Button(action: {
|
||||
self.circularViewModel.startObservingAlarms()
|
||||
self.circularViewModel.startObservingReminders()
|
||||
}) {
|
||||
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