【问题标题】:how can i search(.filter) in different languages?我如何用不同的语言搜索(.filter)?
【发布时间】:2020-11-12 03:17:51
【问题描述】:

我从服务器得到一个对象数组,其中包含一个英文名称字段。 有本地化,从服务器我得到一个对象数组,它们有一个名称字段,总是有英文,当我显示时我已经做了本地化 在一种情况下,例如name = Dog,如果我在搜索中写了一个Dog(语言“ru”),那么什么都没有,如果是Dog,那么一切都很好 我怎样才能正确地做到这一点?


struct TypePet: Codable, Hashable, Equatable {
    
    let id: Int
    let name: String
    let image: URLString?
    
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(name, forKey: .name)
        try container.encode(image, forKey: .image)
    }
    
}

struct TypesPetView: View {
    
    @EnvironmentObject private var languageSettings: UserLanguageSettings
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    
    @State private var searchTypePet: String = ""
    @Binding var listTypesPet: [TypePet]
    @Binding var typePet: TypePet
    
    private var filtredCount: Int {
        return listTypesPet.filter(
            { $0.name.lowercased().contains(searchTypePet.lowercased()) || searchTypePet.isEmpty }
        ).count
    }
    
    init(listTypesPet: Binding<[TypePet]>, typePet: Binding<TypePet>) {
        self._listTypesPet = listTypesPet
        self._typePet = typePet
        UITableView.appearance().backgroundColor = .clear
        UITableView.appearance().tableFooterView = UIView()
    }
    
}

extension TypesPetView {
    
    var body: some View {
        ZStack {
            VStack {
                Text(Translation.typePet, bundle: languageSettings.bundle)
                    .font(.customFont(font: FontNames.notoSansRegular, size: 22))
                    .padding()
                SearchBar(searchText: $searchTypePet)
                Divider()
                List {
                    ForEach(listTypesPet.filter(
                            {
                                $0.name.lowercased().contains(searchTypePet.lowercased()) || searchTypePet.isEmpty
                            }
                    ), id: \.id) { type in
                            TypePetRow(typePet: type)
                                .environmentObject(self.languageSettings)
                            .gesture(
                                TapGesture()
                                    .onEnded {
                                        typePet = type
                                        self.presentationMode.wrappedValue.dismiss()
                                }
                            )
                        }
                }
                .listVisibleIndicator(isShow: false)
                .padding(.trailing, 10.0)
                .resignKeyboardOnDragGesture()
            }
            .resignKeyboardOnDragGesture()
            .padding(.horizontal, 20.0)
            Text(Translation.emptySearch, bundle: languageSettings.bundle)
                .frame(height: 48.0)
                .padding(.horizontal, 44)
                .font(.customFont(font: FontNames.notoSansBold, size: 14))
                .foregroundColor(.white)
                .background(
                    LinearGradient(gradient: Gradients.capsuleCountCharactersGradient, startPoint: .topLeading, endPoint: .bottomTrailing)
                        .cornerRadius(10)
                        .shadow(color: .gray, radius: 2, x: 0, y: 4)
                )
                .clipShape(Capsule())
                .position(x: UIScreen.screenWidth / 2, y: UIScreen.screenWidth / 2)
                .isHidden(filtredCount > 0 ? true : false)
        }
    }
    
}

extension Translation {
    
    static var typePet: LocalizedStringKey {
        return "TypePet"
    }
    
    static var emptySearch: LocalizedStringKey {
        return "EmptySearch"
    }
    
}

struct TypePetRow: View {
    
    @EnvironmentObject private var languageSettings: UserLanguageSettings
    
    var typePet: TypePet
    
}

extension TypePetRow {
    
    var body: some View {
        VStack {
            HStack {
                KFImage(typePet.image?.url)
                    .resizable()
                    .scaledToFill()
                    .frame(width: 48.0, height: 48.0)
                Text(LocalizedStringKey(typePet.name), bundle: languageSettings.bundle)
                    .font(.customFont(font: FontNames.notoSansRegular, size: 16))
                Spacer()
            }
            .background(Color.white)
        }
    }
    
}

enum Language: String {
    
    case ru = "ru"
    case en = "en"
    
}

final class UserLanguageSettings {

    @Published var language: String = UserDefaults.standard.string(forKey: UserDefaultsKeys.language.rawValue) ?? Language.ru.rawValue

    var bundle: Bundle? {
        guard let bundlePath = Bundle.main.path(forResource: language, ofType: "lproj") else { return Bundle(path: "") }
        return Bundle(path: bundlePath)
    }
    
    func changeLanguage(language: Language) {
        let languageString = language.rawValue
        UserDefaults.standard.set(languageString, forKey: UserDefaultsKeys.language.rawValue)
        self.language = languageString
    }
    
    func getCurrentLanguage() -> String {
        guard let currentLanguage = UserDefaults.standard.string(forKey: UserDefaultsKeys.language.rawValue) else { return Language.ru.rawValue }
        return currentLanguage
    }
    
}

extension UserLanguageSettings: ObservableObject {
    
}

在显示中(TypePetRow)适用于不同的语言,并且搜索只有英文,如何使其以当前安装在应用程序中的语言在本地显示(不在系统中,本地化在应用程序,不依赖于系统语言) ?

【问题讨论】:

  • 你可以使用localizedstandardcontains
  • 我试过了,没用,可能是我没有正确实现……我能有一个专门针对我的代码的例子吗? @LeoDabus

标签: ios swift filter swiftui searchbar


【解决方案1】:

确保在提问时使用minimal reproducible example。开发人员只需复制和粘贴即可,几乎无需修改即可使用。

请参阅下文了解可能的解决方案。您的代码中缺少很多内容,因此我无法使其更具体。

import SwiftUI

struct LocalizedSearch: View {
    @Environment(\.locale) var locale
    //Sample Objects
    @State var listTypesPet = [TypePet("dog"), TypePet("cat"), TypePet("snake")]
    @State var searchTypePet: String = "c"
    
    var body: some View {
        VStack{
            SearchBar(text: $searchTypePet)
            Divider()
            List {
                ForEach(listTypesPet.filter {
                    //Replace localizedName with localizedName(bundle:) if needed
                    searchTypePet.isEmpty ? true :
                        $0.localizedName(lang: locale.identifier).lowercased().contains(searchTypePet.lowercased())
                }
                , id: \.self) { pet in
                    TypePetRow(typePet: pet)
                }
            }
        }
    }
}

struct TypePetRow: View {
    @Environment(\.locale) var locale
    var typePet: TypePet
    var body: some View {
        //Replace localizedName with localizedName(bundle:) if needed
        Text(typePet.localizedName(lang: locale.identifier))
    }
}

class TypePet: NSObject {
    var name: String
    var localizedNameSystem: String {
        get{
            //System language
            return NSLocalizedString(name, comment: "Pet.name")
        }
    }
    init(_ name: String) {
        self.name = name
    }
    ///If you want to customize in View
    ///Works with the System's locale
    func localizedName(bundle: Bundle) -> String {
        return NSLocalizedString(name,  bundle: bundle, comment: "Pet.name")
    }
    ///Specific language resources
    func localizedName(lang:String) ->String {
        //Finds only the resources for the specific language
        let path = Bundle.main.path(forResource: lang, ofType: "lproj")
        let bundle = Bundle(path: path!)
        
        return NSLocalizedString(self.name, tableName: nil, bundle: bundle!, value: "", comment: "")
    }
}

struct LocalizedSearch_Previews: PreviewProvider {
    static var previews: some View {
        LocalizedSearch()
            //Change the Environment's locale like this
            .environment(\.locale, .init(identifier: "en"))
        //This would be used in a parent view that references your user settings
        //LocalizedSearch().environment(\.locale, .init(identifier: usrSettings.language))
    }
}

Localizable.stringsen

"cat" = "CAT";
"dog" = "DOG";
"snake" = "SNAKE";

Localizable.stringses

"cat" = "GATO";
"dog" = "PERRO";
"snake" = "CULEBRA";

【讨论】:

  • 不工作,我在应用程序中切换语言,搜索工作只有英文粘贴项目的完整代码,没有变化
  • 尝试使用@Environment(\.locale) vs UserDefaults 见上文
  • 同样,可能很明显,但请确保您的所有宠物名称都列在每种语言的 Localizable.strings 文件中
猜你喜欢
  • 1970-01-01
  • 2011-12-17
  • 1970-01-01
  • 2018-12-01
  • 1970-01-01
  • 2020-10-09
  • 2014-09-01
  • 2017-04-05
  • 2010-10-06
相关资源
最近更新 更多