Skip to content

Instantly share code, notes, and snippets.

@paulw11
Created June 21, 2024 23:15
Show Gist options
  • Save paulw11/85a5e942768b26029f5c9df98f7b425a to your computer and use it in GitHub Desktop.
Save paulw11/85a5e942768b26029f5c9df98f7b425a to your computer and use it in GitHub Desktop.
//
// ContentView.swift
// Filter
//
// Created by Paul Wilkinson on 22/6/2024.
//
import SwiftUI
struct ContentView: View {
@Environment(Filters.self) var filters:Filters
@Environment(Items.self) var items: Items
@State var showFilters=false
var body: some View {
NavigationView {
VStack {
if items.filteredItems.isEmpty {
Text("No items")
} else {
ItemListView(items:items.filteredItems)
}
}
.navigationTitle("Fruits and Vegetables")
.navigationBarItems(trailing:
Button(action: { self.showFilters = true}) {
Image(systemName:"line.3.horizontal.decrease")
})
}
.sheet(isPresented: self.$showFilters, onDismiss: {
self.items.filterItems(filters:self.filters.filters)
}, content: {
FilterSettingsView()
})
.onAppear {
self.items.filterItems(filters:self.filters.filters)
}
}
}
#Preview {
@State var filters=Filters.sampleFilters
@State var items=Items.sampleItems
return ContentView().environment(filters).environment(items)
}
//
// FilterApp.swift
// Filter
//
// Created by Paul Wilkinson on 22/6/2024.
//
import SwiftUI
@main
struct FilterApp: App {
@State var filters=Filters.sampleFilters
@State var items=Items.sampleItems
var body: some Scene {
WindowGroup {
ContentView()
.environment(filters)
.environment(items)
}
}
}
//
// FilterViews.swift
// Filter
//
// Created by Paul Wilkinson on 22/6/2024.
//
import SwiftUI
struct FilterSettingsView:View {
@Environment(Filters.self) var filters:Filters
var body: some View {
Form {
ForEach(FilterType.allCases, id:\.self) { filtertype in
Section( filtertype.rawValue) {
FilterListView(filters:filters.filters(ofType: filtertype))
}
}
}
}
}
struct FilterListView:View {
var filters:[Filter]
var body: some View {
ForEach(filters) { filter in
Toggle(isOn: Binding(get: {
return filter.isOn
}, set: { isOn in
filter.isOn = isOn
})) {
Text(filter.filterValue)
}
}
}
}
//
// ItemListView.swift
// Filter
//
// Created by Paul Wilkinson on 22/6/2024.
//
import SwiftUI
struct ItemListView: View {
var items:[Item]
var body: some View {
List(items) { item in
Text(item.name)
}
}
}
#Preview {
ItemListView(items:Items.sampleItems.filteredItems)
}
//
// Models.swift
// Filter
//
// Created by Paul Wilkinson on 22/6/2024.
//
import Foundation
import SwiftUI
enum FilterType: String, CaseIterable {
case type = "Type"
case color = "Color"
}
@Observable class Filter: Identifiable {
init(type:FilterType, filterValue:String, isOn:Bool=false) {
self.type=type
self.filterValue=filterValue
self.isOn=isOn
}
let id=UUID()
let type: FilterType
let filterValue: String
var isOn: Bool
}
@Observable class Filters {
init(filters:[Filter]) {
self.filters=filters
}
var filters=[Filter]()
func filters(ofType type:FilterType)-> [Filter] {
return filters.filter({ $0.type == type})
}
static var sampleFilters = Filters(filters: [Filter(type: .type, filterValue: "Fruit"),Filter(type: .type, filterValue: "Vegetable"),Filter(type: .color, filterValue: "Green"),Filter(type: .color, filterValue: "Red")])
}
struct Item: Identifiable {
let name: String
let type: String
let color: String
let id = UUID()
}
@Observable class Items {
var filteredItems:[Item]
var allItems:[Item]
init(items:[Item]) {
self.allItems = items
self.filteredItems=items
}
func filterItems(filters:[Filter]) {
let activeFilters = filters.filter{$0.isOn}
if activeFilters.isEmpty {
self.filteredItems = allItems
return
}
self.filteredItems = self.allItems.filter { item in
var typeFiltered = true
var colorFiltered = true
for filter in activeFilters {
switch filter.type {
case .type:
if item.type == filter.filterValue {
typeFiltered = false
}
case .color:
if (item.color ==
filter.filterValue) {
colorFiltered = false
}
}
}
return typeFiltered && colorFiltered
}
}
static var sampleItems=Items(items: [Item(name:"Granny Smith",type: "Fruit", color:"Green"),Item(name:"Macintosh",type: "Fruit", color:"Red"),Item(name:"Red Pepper",type: "Fruit", color:"Red"),Item(name:"Beet",type: "Vegetable", color:"Red"),Item(name:"Broccolli",type: "Vegetable", color:"Green"),Item(name:"Green Pepper",type: "Fruit", color:"Green")])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment