Swift开发:TableView怪物名称搜索栏实现遇报错‘Reference to member 'name' cannot be resolved without a contextual type’求助
Hey there, let's break down why you're hitting this error and get your search bar working properly for your monster compendium.
First, Let's Identify the Root Causes
There are a few key issues in your code that are triggering the error and breaking your search logic:
- Type Mismatch: Your
filteredDatais declared as[String]!(an array of strings), but when the search bar is empty, you're trying to assign a single string (compendium[index].name) to it. The compiler can't resolve this mismatch, hence the "contextual type" error. - Incorrect Filter Usage: You're calling
filteron a singleString(a monster's name), butString.filter()works with individualCharacters—not to filter an array of monsters. This is not what you want when trying to search across all monster names. - Missing Type Keyword: Your
Monsterdefinition is missingstructorclass—Swift needs this to recognize it as a valid type.
Step-by-Step Fixes
1. Correct the Monster Type Definition
First, fix your Monster type by adding the struct keyword (structs are preferred for value types like this in Swift) and follow Swift's naming conventions (lowercase property names):
struct Monster: Codable { let id: Int let name: String let region: String let classification: String let description: String let imageName: String init(id: Int, name: String, region: String, classification: String, description: String, imageName: String) { self.id = id self.name = name self.region = region self.classification = classification self.description = description self.imageName = imageName } }
2. Fix the Search Bar Logic
We need to adjust the searchBar(_:textDidChange:) method to properly filter across all monsters in your compendium array, not just a single one at index.
Option 1: Keep filteredData as [String] (just monster names):
var compendium = [Monster]() var filteredData: [String] = [] // Use a non-optional empty array instead of implicitly unwrapped func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { if searchText.isEmpty { // Load all monster names when search is empty filteredData = compendium.map { $0.name } } else { // Filter monsters whose name contains the search text (case-insensitive) filteredData = compendium .filter { $0.name.range(of: searchText, options: .caseInsensitive) != nil } .map { $0.name } } tableView.reloadData() }
Option 2: Make filteredData [Monster] (more flexible if you need other monster properties later):
var compendium = [Monster]() var filteredData: [Monster] = [] func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { if searchText.isEmpty { filteredData = compendium } else { filteredData = compendium.filter { $0.name.range(of: searchText, options: .caseInsensitive) != nil } } tableView.reloadData() }
Why This Works
- We're now operating on the entire
compendiumarray instead of a single monster atindex, which aligns with your goal of searching all monster names. - The type mismatch is fixed: we assign an array of strings (or monsters) to
filteredData, which matches its declared type. - The
filtermethod is now used on the[Monster]array, where we check each monster's name against the search text—this is exactly what you need for a functional search bar.
内容的提问来源于stack exchange,提问作者TommyScissorFist

