在 Swift (xcode) 中制作可搜索的搜索栏时遇到问题

Posted

技术标签:

【中文标题】在 Swift (xcode) 中制作可搜索的搜索栏时遇到问题【英文标题】:Having problem making a searchable searchbar in Swift (xcode) 【发布时间】:2022-01-22 12:43:34 【问题描述】:

Bin 对 Xcode 进行了一些更改,当它不是基本列表时,我有点卡在如何制作可搜索的搜索栏。我有一页带有标识符的列表,另一页带有嵌入列表的代码。

希望有人比我更nolage。

第 1 页

import SwiftUI

struct Country: Identifiable 
    
    let id = UUID()
    let imageName: String
    let title: String
    let description: String
    let viewCount: Int
    let uploadDate: String
    let url: URL




struct CountryList 
    
        static let AllCountries = [
        Country(imageName: "flag-of-Sweden",
              title: "Sweden",
              description: "lorumibsum lorum ibsum sim sum sam",
              viewCount: 370222,
              uploadDate: "date of post",
              url: URL(string: "https://test.com")!),
        
        Country(imageName: "flag-of-Poland",
              title: "Poland",
              description: "lorumibsum lorum ibsum sim sum sam",
              viewCount: 239150,
              uploadDate: "date of post",
              url: URL(string: "https://test.com")!),
        
        Country(imageName: "flag-of-Russia",
              title: "Russia",
              description: "lorumibsum lorum ibsum sim sum sam",
              viewCount: 162897,
              uploadDate: "date of post",
              url: URL(string: "https://test.com")!),
              
        Country(imageName: "flag-of-Spain",
              title: "Spain",
              description: "lorumibsum lorum ibsum sim sum sam",
              viewCount: 119115,
              uploadDate: "date of post",
              url: URL(string: "https://test.com")!),
        
        Country(imageName: "flag-of-Libya",
              title: "Libya",
              description: "lorumibsum lorum ibsum sim sum sam",
              viewCount: 112213,
              uploadDate: "date of post",
              url: URL(string: "https://test.com")!),

第 2 页这是我在应用中实现列表的第 2 页

import SwiftUI



struct CountryListView: View 
    
    var country: [Country] = CountryList.AllCountries
    

    
    @State private var searchText = ""
    
    var body: some View 
        
        NavigationView 
            
            List(country, id: \.id)  country in
                NavigationLink(destination: CountryDetailView(Country: country), label: 
                    CountryCell(Country: country)
                
                    
            )
                

        
            .navigationTitle("Find your country")
            .searchable(text: $searchText)
            
        
    
        

struct CountryCell: View 
    var Country: Country
   
    
    var body: some View 
        HStack 
            Image(Country.imageName)
                .resizable()
                .scaledToFit()
                .frame(height: 70)
                .cornerRadius(16)
                .padding(.vertical, 4)
                
        
            
            VStack(alignment: .leading, spacing: 5) 
                Text(Country.title)
                    .fontWeight(.semibold)
                    .lineLimit(2)
                    .minimumScaleFactor(0.5)
                
                Text(Country.uploadDate)
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            
        
        
    
    var searchResults: [String] 
        if searchText.isEmpty 
            return Country
         else 
            return Country.filter( $0.contains(searchText))
        
    




struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        CountryListView()
       
    

【问题讨论】:

代码的哪一部分不起作用?你还有什么要实现的? 【参考方案1】:

无论您何时使用列表,搜索栏及其模式都不会改变。您感到困惑的地方是不了解您正在返回数据类型的数组,而不仅仅是字符串。 [String] 经常被用作示例,因为它们很简单,但混淆来自于您的搜索文本也是 String 的事实。实际上,您返回的是 [Type],其中 Type 是您的数据类型。在这种情况下,即为Country。因此你的代码变成了这样:

struct CountryListView: View 
    
    // You should just declare this as @State var, NEVER just var in a struct.
    // If you are not planning to mutate this list, declare it with let
    // Also, you reused "Country" which caused the compiler to be confused.
    // Types should begin with a capital letter and be singular
    // Names of singular instances should be lowercased.
    // Names of arrays of a type should be lowercased and plural
    // You will see I changed the instance you called Country to countries.
    @State private var countries = CountryList.allCountries
    @State private var searchText = ""
    
    var body: some View 
        
        NavigationView 
            // The list uses searchResults which is an [Country]
            // Since Country is Identifiable, you do not need the id:\.id in the list.
            List(searchResults)  country in
                // You didn't provide CountryDetail, so I used CountryCell for both
                NavigationLink(destination: CountryCell(country: country), label: 
                    CountryCell(country: country)
                )
            
            .navigationTitle("Find your country")
            .searchable(text: $searchText)
        
    
    
    var searchResults: [Country] 
        if searchText.isEmpty 
            return countries
         else 
            return countries.filter( $0.title.lowercased().contains(searchText.lowercased()))
        
    

    struct CountryCell: View 
        
        let country: Country
        
        var body: some View 
            HStack 
                // Since we don't have the flag assets, I just used an SF Symbol
                // Please do this sort of substitution before you post.
                Image(systemName: country.imageName)
                    .resizable()
                    .scaledToFit()
                    .frame(height: 70)
                    .cornerRadius(16)
                    .padding(.vertical, 4)
                
                VStack(alignment: .leading, spacing: 5) 
                    Text(country.title)
                        .fontWeight(.semibold)
                        .lineLimit(2)
                        .minimumScaleFactor(0.5)
                    
                    Text(country.uploadDate)
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                
            
        
    


struct CountryList 
    
    static let allCountries = [
        // Substitued SF Font for imageName
        Country(imageName: "flag",
                title: "Sweden",
                description: "lorumibsum lorum ibsum sim sum sam",
                viewCount: 370222,
                uploadDate: "date of post",
                url: URL(string: "https://test.com")!),
        ...]

【讨论】:

以上是关于在 Swift (xcode) 中制作可搜索的搜索栏时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 搜索控制器 - 在开始时显示搜索栏 (Swift 4)

在 Swift 中搜索字典数组的值

UISearchbar 并在查看控制器 xcode swift 中传递数据

自动填充用户名和密码 WKWebview Swift 3 Xcode

Xcode 9.2 中缺少标头搜索路径、库路径和链接路径部分

如何使用swift从Xcode coco app运行像FFMPEG这样的终端程序?