[ADD] Search bar for BrowseView on iOS 15

This commit is contained in:
Fabian Thies
2022-12-12 19:18:57 +01:00
parent 294ba12391
commit 3ce4451da4
5 changed files with 73 additions and 33 deletions

View File

@@ -0,0 +1,17 @@
//
// StoreApp+Searchable.swift
// SideStore
//
// Created by Fabian Thies on 01.12.22.
// Copyright © 2022 SideStore. All rights reserved.
//
import AltStoreCore
extension StoreApp: Filterable {
func matches(_ searchText: String) -> Bool {
searchText.isEmpty ||
self.name.lowercased().contains(searchText.lowercased()) ||
self.developerName.lowercased().contains(searchText.lowercased())
}
}

View File

@@ -0,0 +1,23 @@
//
// Filterable.swift
// SideStore
//
// Created by Fabian Thies on 01.12.22.
// Copyright © 2022 SideStore. All rights reserved.
//
import Foundation
protocol Filterable {
func matches(_ searchText: String) -> Bool
}
extension Collection where Element: Filterable {
func matches(_ searchText: String) -> Bool {
self.contains(where: { $0.matches(searchText) })
}
func items(matching searchText: String) -> [Element] {
self.filter { $0.matches(searchText) }
}
}

View File

@@ -0,0 +1,29 @@
//
// Modifiers.swift
// SideStore
//
// Created by Fabian Thies on 01.12.22.
// Copyright © 2022 SideStore. All rights reserved.
//
import SwiftUI
extension View {
@ViewBuilder func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View {
if condition {
transform(self)
} else {
self
}
}
@ViewBuilder func searchable(text: Binding<String>, placeholder: String) -> some View {
if #available(iOS 15.0, *) {
self.searchable(text: text, prompt: Text(placeholder))
} else {
self
}
}
}

View File

@@ -14,7 +14,7 @@ struct BrowseAppPreviewView: View {
let storeApp: StoreApp
var body: some View {
VStack {
VStack(spacing: 16) {
AppRowView(app: storeApp)
if let subtitle = storeApp.subtitle {

View File

@@ -15,11 +15,11 @@ struct BrowseView: View {
NSSortDescriptor(keyPath: \StoreApp.sortIndex, ascending: true),
NSSortDescriptor(keyPath: \StoreApp.name, ascending: true),
NSSortDescriptor(keyPath: \StoreApp.bundleIdentifier, ascending: true)
]/*, predicate: NSPredicate(format: "%K != %@", #keyPath(StoreApp.bundleIdentifier), StoreApp.altstoreAppID)*/)
], predicate: NSPredicate(format: "%K != %@", #keyPath(StoreApp.bundleIdentifier), StoreApp.altstoreAppID))
var apps: FetchedResults<StoreApp>
var filteredApps: [StoreApp] {
apps.filter { $0.matches(self.searchText) }
apps.items(matching: self.searchText)
}
@State
@@ -31,7 +31,7 @@ struct BrowseView: View {
var body: some View {
ScrollView {
LazyVStack(spacing: 24) {
LazyVStack(spacing: 32) {
ForEach(filteredApps, id: \.bundleIdentifier) { app in
NavigationLink {
AppDetailView(storeApp: app)
@@ -68,32 +68,3 @@ struct BrowseView_Previews: PreviewProvider {
BrowseView()
}
}
extension StoreApp {
func matches(_ searchText: String) -> Bool {
searchText.isEmpty ||
self.name.lowercased().contains(searchText.lowercased()) ||
self.developerName.lowercased().contains(searchText.lowercased())
}
}
extension View {
@ViewBuilder func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View {
if condition {
transform(self)
} else {
self
}
}
@ViewBuilder func searchable(text: Binding<String>, placeholder: String) -> some View {
if #available(iOS 15.0, *) {
self.searchable(text: text, prompt: Text(placeholder))
} else {
self
}
}
}