Vous pouvez filtrer tous les caractères thats pas une lettre de votre Chaîne avant d'effectuer votre recherche. La même chose s'applique aux éléments de source de données de vue de table. En outre, comme mentionné par rmaddy vous devez mettre en œuvre une affaire recherche insensible:
extension UnicodeScalar {
init?(_ character: Character) {
self.init(character.string)
}
}
extension Character {
var unicodeScalar: UnicodeScalar? {
return UnicodeScalar(self)
}
var string: String {
return String(self)
}
}
extension String {
func containsCaseInsensitive(_ string: String) -> Bool {
return range(of: string, options: .caseInsensitive) != nil
}
var letters: String {
return String(characters.filter{
guard let unicodeScalar = $0.unicodeScalar else { return false }
return CharacterSet.letters.contains(unicodeScalar)
})
}
}
Test:
let search = "st george"
let tableViewSource = ["Apple", "Orange", "Banana", "St. George"]
let filtered = tableViewSource.filter {
$0.letters.containsCaseInsensitive(search.letters)
}
print(filtered) // ["St. George"]
Si vous souhaitez littéralement juste enlever la ponctuation de votre chaîne (notez que garderait les espaces dans votre chaîne), vous pouvez faire comme suit:
extension String {
var removingPunctuation: String {
return String(characters.filter {
guard let unicodeScalar = $0.unicodeScalar else { return true }
return !CharacterSet.punctuationCharacters.contains(unicodeScalar)
})
}
}
Test:
let filtered = tableViewSource.filter {
$0.removingPunctuation.caseInsensitiveContains(search.removingPunctuation)
}
print(filtered) // ["St. George"]
Si vous souhaitez mettre en œuvre la même logique que Xcode autocomplete vous devez faire une recherche pour chaque personnage et changer le startIndex de la chaîne recherché:
extension String {
func containsCaseInsensitiveCharactersInSequence(_ string: String) -> Bool {
var found = 0
var start = startIndex
string.characters.forEach {
while let range = range(of: String($0), options: .caseInsensitive, range: start..<endIndex) {
found += 1
start = range.upperBound
break
}
}
return found == string.characters.count
}
}
Test de terrain de jeu:
let search = "stgrge"
let tableViewSource = ["Apple", "Orange", "Banana", "St. George"]
let filtered = tableViewSource.filter {
$0.removingPunctuation.containsCaseInsensitiveCharactersInSequence(search.removingPunctuation)
}
print(filtered) // ["St. George"]
Il devrait également faire une recherche insensible à la casse (le plus probable). – rmaddy