不搜索第一个字母
Not searching the first letter
我正在将我的 plist 加载到 TableView 中,一切正常,但现在当我搜索某些内容时,它不考虑第一个字母。下面是 directory.plist 和我的 Main.storyboard
为了正确加载 plist,我将以下代码放在 didFinishLaunchingWithOptions
:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if let url = Bundle.main.url(forResource: "directory", withExtension: "plist"), let array = NSArray(contentsOf: url) as? [[String:Any]] {
Shared.instance.employees = array.map{Employee(dictionary: [=10=])}
}
return true
}
我还有一个结构可以帮助我加载我所有的东西:
struct EmployeeDetails {
let functionary: String
let imageFace: String
let phone: String
init(dictionary: [String: Any]) {
self.functionary = (dictionary["Functionary"] as? String) ?? ""
self.imageFace = (dictionary["ImageFace"] as? String) ?? ""
self.phone = (dictionary["Phone"] as? String) ?? ""
}
}
struct Employee {
let position: String
let name: String
let details: [EmployeeDetails] // [String:Any]
init(dictionary: [String: Any]) {
self.position = (dictionary["Position"] as? String) ?? ""
self.name = (dictionary["Name"] as? String) ?? ""
let t = (dictionary["Details"] as? [Any]) ?? []
self.details = t.map({EmployeeDetails(dictionary: [=11=] as! [String : Any])})
}
}
struct Shared {
static var instance = Shared()
var employees: [Employee] = []
}
到这里,一切都很好运行!现在我尝试插入SearchView时遇到了麻烦,看看我到现在做了什么:
class Page1: UITableViewController, UISearchBarDelegate {
@IBOutlet weak var searchBar: UISearchBar!
var employeesSearching = [Employee]()
var isSearching : Bool = false
override func viewDidLoad() {
super.viewDidLoad()
self.searchBar.delegate = self
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.isSearching == true {
return self.employeesSearching.count
} else {
return Shared.instance.employees.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell1
let employee = Shared.instance.employees[indexPath.row]
if self.isSearching == true {
cell.nameLabel.text = self.employeesSearching[indexPath.row].name
cell.positionLabel.text = self.employeesSearching[indexPath.row].position
} else {
cell.nameLabel.text = employee.name
cell.positionLabel.text = employee.position
}
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if self.searchBar.text!.isEmpty {
self.isSearching = false
self.tableView.reloadData()
} else {
self.isSearching = true
self.employeesSearching.removeAll(keepingCapacity: false)
for i in 0..<Shared.instance.employees.count {
let listItem : Employee = Shared.instance.employees[i]
if listItem.name.range(of: self.searchBar.text!.lowercased()) != nil {
self.employeesSearching.append(listItem)
}
}
self.tableView.reloadData()
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? Page2,
let indexPath = tableView.indexPathForSelectedRow {
destination.newPage = Shared.instance.employees[indexPath.row]
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
我在搜索的第一个字母上遇到问题。看看:
问题出在这一行:
if listItem.name.range(of: self.searchBar.text!.lowercased()) != nil {
您正在员工姓名的常规文本中查找小写版本的搜索文本。
文本 "John Smith" 不包含搜索文本 "j"。但它确实包含搜索文本 "ohn".
快速解决方法是将该行代码更改为:
if listItem.name.lowercased().range(of: self.searchBar.text!.lowercased()) != nil {
现在比较员工姓名和搜索文本的小写版本。所以现在它将匹配,因为 "john smith" 包含 "j".
顺便说一句 - 一遍又一遍地小写搜索文本是低效的。还有一种更好的方法来编写循环代码。我会将其更改为:
self.employeesSearching.removeAll(keepingCapacity: false)
let searchText = self.searchBar.text!.lowercased()
for employee in Shared.instance.employees {
if employee.name.lowercased().range(of: searchText) != nil {
self.employeesSearching.append(employee)
}
}
更简单的方法是将该代码替换为:
let searchText = self.searchBar.text!.lowercased()
self.employeesSearching = Shared.instance.employees.filter { [=13=].name.lowercased().range(of: searchText) != nil
}
要在名称或位置中搜索文本,只需更新比较表达式:
if employee.name.lowercased().range(of: searchText) != nil || employee.position.lowercased().range(of: searchText) != nil {
如果您使用 filter
,请进行类似的更改。
我正在将我的 plist 加载到 TableView 中,一切正常,但现在当我搜索某些内容时,它不考虑第一个字母。下面是 directory.plist 和我的 Main.storyboard
为了正确加载 plist,我将以下代码放在 didFinishLaunchingWithOptions
:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if let url = Bundle.main.url(forResource: "directory", withExtension: "plist"), let array = NSArray(contentsOf: url) as? [[String:Any]] {
Shared.instance.employees = array.map{Employee(dictionary: [=10=])}
}
return true
}
我还有一个结构可以帮助我加载我所有的东西:
struct EmployeeDetails {
let functionary: String
let imageFace: String
let phone: String
init(dictionary: [String: Any]) {
self.functionary = (dictionary["Functionary"] as? String) ?? ""
self.imageFace = (dictionary["ImageFace"] as? String) ?? ""
self.phone = (dictionary["Phone"] as? String) ?? ""
}
}
struct Employee {
let position: String
let name: String
let details: [EmployeeDetails] // [String:Any]
init(dictionary: [String: Any]) {
self.position = (dictionary["Position"] as? String) ?? ""
self.name = (dictionary["Name"] as? String) ?? ""
let t = (dictionary["Details"] as? [Any]) ?? []
self.details = t.map({EmployeeDetails(dictionary: [=11=] as! [String : Any])})
}
}
struct Shared {
static var instance = Shared()
var employees: [Employee] = []
}
到这里,一切都很好运行!现在我尝试插入SearchView时遇到了麻烦,看看我到现在做了什么:
class Page1: UITableViewController, UISearchBarDelegate {
@IBOutlet weak var searchBar: UISearchBar!
var employeesSearching = [Employee]()
var isSearching : Bool = false
override func viewDidLoad() {
super.viewDidLoad()
self.searchBar.delegate = self
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.isSearching == true {
return self.employeesSearching.count
} else {
return Shared.instance.employees.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell1
let employee = Shared.instance.employees[indexPath.row]
if self.isSearching == true {
cell.nameLabel.text = self.employeesSearching[indexPath.row].name
cell.positionLabel.text = self.employeesSearching[indexPath.row].position
} else {
cell.nameLabel.text = employee.name
cell.positionLabel.text = employee.position
}
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if self.searchBar.text!.isEmpty {
self.isSearching = false
self.tableView.reloadData()
} else {
self.isSearching = true
self.employeesSearching.removeAll(keepingCapacity: false)
for i in 0..<Shared.instance.employees.count {
let listItem : Employee = Shared.instance.employees[i]
if listItem.name.range(of: self.searchBar.text!.lowercased()) != nil {
self.employeesSearching.append(listItem)
}
}
self.tableView.reloadData()
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? Page2,
let indexPath = tableView.indexPathForSelectedRow {
destination.newPage = Shared.instance.employees[indexPath.row]
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
我在搜索的第一个字母上遇到问题。看看:
问题出在这一行:
if listItem.name.range(of: self.searchBar.text!.lowercased()) != nil {
您正在员工姓名的常规文本中查找小写版本的搜索文本。
文本 "John Smith" 不包含搜索文本 "j"。但它确实包含搜索文本 "ohn".
快速解决方法是将该行代码更改为:
if listItem.name.lowercased().range(of: self.searchBar.text!.lowercased()) != nil {
现在比较员工姓名和搜索文本的小写版本。所以现在它将匹配,因为 "john smith" 包含 "j".
顺便说一句 - 一遍又一遍地小写搜索文本是低效的。还有一种更好的方法来编写循环代码。我会将其更改为:
self.employeesSearching.removeAll(keepingCapacity: false)
let searchText = self.searchBar.text!.lowercased()
for employee in Shared.instance.employees {
if employee.name.lowercased().range(of: searchText) != nil {
self.employeesSearching.append(employee)
}
}
更简单的方法是将该代码替换为:
let searchText = self.searchBar.text!.lowercased()
self.employeesSearching = Shared.instance.employees.filter { [=13=].name.lowercased().range(of: searchText) != nil
}
要在名称或位置中搜索文本,只需更新比较表达式:
if employee.name.lowercased().range(of: searchText) != nil || employee.position.lowercased().range(of: searchText) != nil {
如果您使用 filter
,请进行类似的更改。