M6L5 : Enhancing the List View

In lesson 5 of module 6 of the CWC+ iOS Databases course, Chris shows us how to add a search box to our RecipeListView.swift by using a filter with our Core Data.

...
@State private var filterBy = ""
...
@FetchRequest(
    sortDescriptors: [NSSortDescriptor(key: "name", ascending: true)]
)
private var recipes: FetchedResults<Recipe>

private var filteredRecipes: [Recipe] {
    if filterBy.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
        return Array(recipes)
    } else {
        return recipes.filter { r in
            return r.name.contains(filterBy)
        }
    }
}
...
var body: some View {
    ...
    ForEach(filteredRecipes) { r in
        ...
        SearchBarView(
            filterText: $filterBy,
            inFocus: $inFocus    
        )
        ...
    }
    ...
}

And then we have our SearchBarView sub-view:

import SwiftUI

struct SearchBarView: View {
    
    @Binding var filterBy: String
    
    var body: some View {
        ZStack {
            Rectangle()
                .foregroundColor(.white)
                .cornerRadius(5)
                .shadow(radius: 4)
            
            HStack {
                Image(systemName: "magnifyingglass")
                TextField("Filter by...", text: $filterBy)
                Button {
                    filterBy = ""
                } label: {
                    Image(systemName: "multiply.circle.fill")
                }
            }
            .padding()
        }
        .frame(height: 48)
        .foregroundColor(.gray)
    }
}

One of the problems this lesson revealed was that the on-screen keyboard, which automatically pops up when the user clicks into the TextField, isn’t automatically dismissed when they click outside the TextField.

I’ve summarised this here: Dismissing the Keyboard (iOS 15)