mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
[ADD] Search bar for BrowseView on iOS 15
This commit is contained in:
17
AltStore/Extensions/StoreApp+Filterable.swift
Normal file
17
AltStore/Extensions/StoreApp+Filterable.swift
Normal 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())
|
||||
}
|
||||
}
|
||||
23
AltStore/Protocols/Filterable.swift
Normal file
23
AltStore/Protocols/Filterable.swift
Normal 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) }
|
||||
}
|
||||
}
|
||||
29
AltStore/View Extensions/Modifiers.swift
Normal file
29
AltStore/View Extensions/Modifiers.swift
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user