Reputation: 1810
I have a list of professional accounts that each contains a list of professional items.
I want to sort this list of professional accounts by retrieving all the professional items that contain a specific text.
Code :
func filterContentForSearchText(searchText: String) {
self.listProfessionalAccountsFiltered = self.listProfessionalAccounts
for professionalAccount in self.listProfessionalAccountsFiltered {
professionalAccount.listProfessionalItems = searchText.isEmpty ? professionalAccount.listProfessionalItems : professionalAccount.listProfessionalItems.filter{ $0.title.lowercased().contains(searchText.lowercased()) }
}
self.listProfessionalAccountsFiltered = searchText.isEmpty ? self.listProfessionalAccounts : self.listProfessionalAccounts.filter { $0.listProfessionalItems.count > 0 }
self.tableView.reloadData()
}
The search works well but when I delete, I lose data :
Why ?
EDIT
All code :
class ChangeAccountViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var topInset: CGFloat = 0.0
var initialTouchPoint = CGPoint.zero
var listProfessionalAccounts = [ProfessionalAccount]()
var listProfessionalAccountsFiltered = [ProfessionalAccount]()
override func viewDidLoad() {
super.viewDidLoad()
self.setupUI()
self.setupData()
}
func setupUI() {
if #available(iOS 11.0, *) {
self.topInset = UIApplication.shared.keyWindow?.safeAreaInsets.top ?? 0
}
self.view.frame = CGRect(x: 0, y: self.topInset, width: self.view.frame.size.width, height: self.view.frame.size.height)
}
func setupData() {
self.listProfessionalAccounts.append(DATA1)
self.listProfessionalAccounts.append(DATA2)
self.listProfessionalAccounts.append(DATA3)
self.listProfessionalAccounts.append(DATA4)
self.listProfessionalAccountsFiltered = self.listProfessionalAccounts
}
@IBAction func close(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
@IBAction func handleGesture(_ sender: UIPanGestureRecognizer) {
let touchPoint = sender.location(in: self.view?.window)
if sender.state == UIGestureRecognizer.State.began {
initialTouchPoint = touchPoint
} else if sender.state == UIGestureRecognizer.State.changed {
if touchPoint.y - initialTouchPoint.y > 0 {
self.view.frame = CGRect(x: 0, y: self.topInset + touchPoint.y - initialTouchPoint.y, width: self.view.frame.size.width, height: self.view.frame.size.height)
}
} else if sender.state == UIGestureRecognizer.State.ended || sender.state == UIGestureRecognizer.State.cancelled {
if touchPoint.y - initialTouchPoint.y > (view.bounds.height/3) {
self.dismiss(animated: true, completion: nil)
} else {
UIView.animate(withDuration: 0.3, animations: {
self.view.frame = CGRect(x: 0, y: self.topInset, width: self.view.frame.size.width, height: self.view.frame.size.height)
})
}
}
}
}
extension ChangeAccountViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return self.listProfessionalAccountsFiltered.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.listProfessionalAccountsFiltered[section].listProfessionalItems.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.listProfessionalAccountsFiltered[section].title
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = self.listProfessionalAccountsFiltered[indexPath.section].listProfessionalItems[indexPath.row].title
return cell
}
}
extension ChangeAccountViewController: UISearchControllerDelegate, UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
self.filterContentForSearchText(searchText: searchText)
}
func filterContentForSearchText(searchText: String) {
self.listProfessionalAccountsFiltered = self.listProfessionalAccounts
for professionalAccount in self.listProfessionalAccountsFiltered {
professionalAccount.listProfessionalItems = searchText.isEmpty ? professionalAccount.listProfessionalItems : professionalAccount.listProfessionalItems.filter{ $0.title.lowercased().contains(searchText.lowercased()) }
}
self.listProfessionalAccountsFiltered = searchText.isEmpty ? self.listProfessionalAccounts : self.listProfessionalAccountsFiltered.filter { $0.listProfessionalItems.count > 0 }
self.tableView.reloadData()
}
}
ANSWER :
func filterContentForSearchText(searchText: String) {
self.listProfessionalAccountsFiltered = self.listProfessionalAccounts.compactMap { professionalAccount in
let filteredProfessionalAccountItems = professionalAccount.listProfessionalItems.filter { $0.title.lowercased().contains(searchText.lowercased()) }
return searchText.isEmpty ? professionalAccount : (filteredProfessionalAccountItems.isEmpty ? nil : ProfessionalAccount(id: professionalAccount.id, title: professionalAccount .title, listProfessionalItems: filteredProfessionalAccountItems))
}
self.tableView.reloadData()
}
Upvotes: 1
Views: 668
Reputation: 4521
Looks like you modify listProfessionalAccounts
even if you copy it. Add the following init
function to ProfessionalAccount
if you still don't have it:
init(id: ID, title: TITLE, listProfessionalItems: LIST) {
self.id = id
self.title = title
self.listProfessionalItems = listProfessionalItems
}
Use the following code to update listProfessionalAccountsFiltered
:
func filterContentForSearchText(searchText: String) {
self.listProfessionalAccountsFiltered = self.listProfessionalAccounts.compactMap { professionalAccount in
guard !searchText.isEmpty else {
return professionalAccount
}
let filteredProfessionalAccountItems = professionalAccount.listProfessionalItems.filter { $0.title.lowercased().contains(searchText.lowercased()) }
return filteredProfessionalAccountItems.isEmpty ? nil : ProfessionalAccount(id: professionalAccount.id, title: professionalAccount.title, listProfessionalItems: filteredProfessionalAccountItems)
}
self.tableView.reloadData()
}
Upvotes: 1