You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

  1. Type Mismatch: Your filteredData is 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.
  2. Incorrect Filter Usage: You're calling filter on a single String (a monster's name), but String.filter() works with individual Characters—not to filter an array of monsters. This is not what you want when trying to search across all monster names.
  3. Missing Type Keyword: Your Monster definition is missing struct or class—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 compendium array instead of a single monster at index, 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 filter method 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 12:07:48