gpt4 book ai didi

ios - 从过滤数据崩溃的 TableView 中删除项目

转载 作者:行者123 更新时间:2023-11-28 05:39:35 25 4
gpt4 key购买 nike

我正在尝试从我的表格 View 中删除一个提醒,但是当它来自于通过搜索栏进行过滤时,当没有进行过滤时,常规删除工作完美,但是当搜索栏中有过滤器时,它会使应用程序崩溃.

这是代码;

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

var updatedArray = [Reminder]()

if editingStyle == .delete {
if filtered == false {
reminders.remove(at: indexPath.row)
tableReminders.deleteRows(at: [indexPath], with: .fade)
convertAndSaveInDDPath(array: reminders)
}
if filtered == true {
updatedArray = reminders.filter{ $0.reminderName != filterData[indexPath.row].reminderName}
print(updatedArray)
reminders = updatedArray
tableReminders.deleteRows(at: [indexPath], with: .fade)
tableReminders.reloadData()
//convertAndSaveInDDPath(array: reminders)

}

}
}

如有任何帮助,我们将不胜感激,谢谢。

编辑(新代码):

  public struct Reminder {
var reminderName : String
var reminderPriority : String
var reminderDate : Date
var reminderStatus : String
var reminderSavedTime : Date
}

var reminders : [Reminder] = []

var filtered : Bool = false



public func getFilePath(fileName:String) -> String {
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = NSURL(fileURLWithPath: path)
let filePath = url.appendingPathComponent(fileName)?.path
return filePath!
}

public func convertAndSaveInDDPath (array:[Reminder]) {
let objCArray = NSMutableArray()
for obj in array {

// we have to do something like this as we can't store struct objects directly in NSMutableArray
let dict = NSDictionary(objects: [obj.reminderName ,obj.reminderPriority, obj.reminderDate, obj.reminderStatus, obj.reminderSavedTime ], forKeys: ["reminderName" as NSCopying,"reminderPriority" as NSCopying, "reminderDate" as NSCopying, "reminderStatus" as NSCopying, "reminderSavedTime" as NSCopying])
objCArray.add(dict)
}

// this line will save the array in document directory path.
objCArray.write(toFile: getFilePath(fileName: "remindersArray"), atomically: true)
}

public func getArray() -> [Reminder]? {
var remindersArray = [Reminder]()
if let _ = FileManager.default.contents(atPath: getFilePath(fileName: "remindersArray")) {
let array = NSArray(contentsOfFile: getFilePath(fileName: "remindersArray"))
for (_,userObj) in array!.enumerated() {
let reminderDict = userObj as! NSDictionary
let reminder = Reminder(reminderName: (reminderDict.value(forKey: "reminderName") as? String)!, reminderPriority: (reminderDict.value(forKey: "reminderPriority") as? String)!, reminderDate: (reminderDict.value(forKey: "reminderDate") as? Date)!, reminderStatus: (reminderDict.value(forKey: "reminderStatus") as? String)!, reminderSavedTime: (reminderDict.value(forKey: "reminderSavedTime") as? Date)!)
remindersArray.append(reminder)

}
return remindersArray
}
return nil
}

class ViewController: UIViewController, UITableViewDataSource, UITextFieldDelegate, UITableViewDelegate, UISearchBarDelegate {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Reminder Section
return filteredReminder.count
}

@IBOutlet var searchBar: UISearchBar!
var filterData = [Reminder]()
var originalReminder = [Reminder]() // original data array.
var filteredReminder = [Reminder]() // data that used to show in tableview.


var sortedAZState : Bool = false
var sortedTimeState : Bool = false
var sortedPrioState : Bool = false

@IBOutlet weak var tableReminders: UITableView!
@IBOutlet weak var timeSortBtn: UIButton!
@IBOutlet weak var sortBtn: UIButton!
@IBOutlet weak var prioritySortBtn: UIButton!

@IBAction func BtnSort(_ sender: Any) {
sortList(sender: sortBtn) // sorts by a-z through the sort function
}

@IBAction func btnSortTime(_ sender: Any) {
sortList(sender: timeSortBtn)
}

@IBAction func btnSortPriority(_ sender: Any) {
sortList(sender: prioritySortBtn)
}


func sortList(sender: UIButton) { // should probably be called sort and not filter


if sender.tag == 1 && sortedAZState == false {
reminders.sort() { $0.reminderName < $1.reminderName } // sort the reminder by name
tableReminders.reloadData(); // notify the table view the data has changed
print("sender.tag 1")
sortedAZState = true
}

else if sender.tag == 1 && sortedAZState == true {
reminders.sort() { $0.reminderName > $1.reminderName } // sort the reminder by name
tableReminders.reloadData(); // notify the table view the data has changed
print("sender.tag 1")
sortedAZState = false
}

else if sender.tag == 2 && sortedTimeState == false {
reminders.sort { $0.reminderSavedTime.compare($1.reminderSavedTime) == .orderedAscending }
tableReminders.reloadData();
print("sender.tag 2")
sortedTimeState = true
}

else if sender.tag == 2 && sortedTimeState == true {
reminders.sort { $0.reminderSavedTime.compare($1.reminderSavedTime) == .orderedDescending }
tableReminders.reloadData();
print("sender.tag 2")
sortedTimeState = false
}

else if sender.tag == 3 && sortedPrioState == false {
reminders.sort() { $0.reminderPriority.count < $1.reminderPriority.count } // sort the reminder by priority
tableReminders.reloadData(); // notify the table view the data has changed
print("sender.tag 3")
sortedPrioState = true
}

else if sender.tag == 3 && sortedPrioState == true {
reminders.sort() { $0.reminderPriority.count > $1.reminderPriority.count } // sort the reminder by priority
tableReminders.reloadData(); // notify the table view the data has changed
print("sender.tag 3")
sortedPrioState = false
}

}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

// Create an object of the dynamic cell "plainCell"
let cell = tableView.dequeueReusableCell(withIdentifier: "ReminderTableViewCell", for: indexPath) as! ReminderTableViewCell
// Depending on the section, fill the textLabel with the relevant text
// Reminder Section


cell.reminderLabel.text = filteredReminder[indexPath.row].reminderName

if filteredReminder[indexPath.row].reminderPriority == "!" {
let yourImage: UIImage = UIImage(named: "lowpriority")!
cell.priorityImage.image = yourImage
}

else if filteredReminder[indexPath.row].reminderPriority == "!!" {
let yourImage: UIImage = UIImage(named: "mediumpriority")!
cell.priorityImage.image = yourImage
}

else if filteredReminder[indexPath.row].reminderPriority == "!!!" {
let yourImage: UIImage = UIImage(named: "highpriority")!
cell.priorityImage.image = yourImage
}

/* I DON'T KNOW WHAT THIS COMPLETION FOR, HOPE IT IS WORKING A/C TO YOUR NEED. */

// cell.completeButtonAction = { [unowned self] in
// let reminderCall = reminders[indexPath.row].reminderName
// let alert = UIAlertController(title: "Complete!", message: "You have completed \(reminderCall).", preferredStyle: .alert)
// let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
// alert.addAction(okAction)
//
// reminders.remove(at: indexPath.row)
// self.tableReminders.deleteRows(at: [indexPath], with: .fade)
// convertAndSaveInDDPath(array: reminders)
//
// print("reminder deleted")
//
// self.present(alert, animated: true, completion: nil)
// }
//


return cell

}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
print(reminders[indexPath.row].reminderName)

let selectedReminder = reminders[indexPath.row].reminderName
let destinationVC = EditReminderViewController()
destinationVC.reminderPassed = selectedReminder

performSegue(withIdentifier: "editSegue", sender: indexPath)
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

if editingStyle == .delete {

filteredReminder.remove(at: indexPath.row)
tableReminders.deleteRows(at: [indexPath], with: .fade)

print(filteredReminder)
convertAndSaveInDDPath(array: filteredReminder) // UNCOMMENT THIS

}
}

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

// var decapValue = searchBar.text?.lowercased()

// print(decapValue!)
// print(LinearSearch(searchText: decapValue!, array: reminders))

if searchBar.text != "" {
self.filteredReminder = originalReminder.filter({ reminder -> Bool in
return reminder.reminderName.lowercased().contains(searchText.lowercased())
})
}
else {
self.filteredReminder = self.originalReminder
}
tableReminders.reloadData()

// print(filterData)



}
/*
func LinearSearch(searchText: String, array: [Reminder]) -> Bool { // search function to return a true or a false bool (contains two parameneters, search value and array
for i in reminders { // cycles through each element in the array
if i.reminderName.lowercased().contains(searchText) { // if element = search (return true)
filterData.append(i)
print(filterData)
return true
}
}


return false // returns false if no element comes back to equal the searchValue
}
*/

@IBAction func btnAdd(_ sender: Any) {
performSegue(withIdentifier: "addSegue", sender: (Any).self)
}

override func viewDidLoad() {
super.viewDidLoad() // example cell
// reminders.append(Reminder(reminderName: "HOMEWORK", reminderPriority: "LOW", reminderDate: "4324", reminderStatus: "INCOMPLETE"))

tableReminders.dataSource = self
tableReminders.delegate = self

searchBar.delegate = self

tableReminders.reloadData()

// print file path of array saved
// print(getFilePath(fileName: "remindersArray"))

let reminderRetrievedArray = getArray()
reminders = reminderRetrievedArray!
originalReminder = reminders
gfilteredReminder = reminders

// Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}



}

我不知道你在找哪个代码,所以这里有所有的代码。但是是的,你是对的,它一次删除一个,但它正在保存一个空数组以供下次打开时加载。

最佳答案

以下是使您的代码完美、干净、易于理解和工作的更改。如果您有任何疑问,请发表评论,如果答案有任何错误,请更新答案。


  1. 您不需要维护标记已过滤。我假设你有两个数组

    var originalReminder = [Reminder]()  // original data array.
    var filteredReminder = [Reminder]() // data that used to show in tableview.
  2. ViewDidLoad 中,在 originalReminder 中设置正确的数据,如果您想在表中显示所有原始数据,则在 filteredReminder< 中分配相同的数据 还有。

  3. 现在我们将使用 1 个数组管理 TableView ,即 filteredReminder,如果搜索栏文本为空,那么我们会将原始数组分配给过滤后的数组。所以你的 searchbar textDidChange 看起来像这样。

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    if searchBar.text != "" {
    self.filteredReminder = originalReminder.filter({ reminder -> Bool in
    return reminder.reminderName.lowercased().contains(searchText.lowercased())
    })
    }
    else {
    self.filteredReminder = self.originalReminder
    }
    tableReminders.reloadData()
    }
  4. 您可以像下面这样从 cellForRow 中删除冗余代码

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return filteredReminder.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Create an object of the dynamic cell "plainCell"
    let cell = tableView.dequeueReusableCell(withIdentifier: "ReminderTableViewCell", for: indexPath) as! ReminderTableViewCell
    // Depending on the section, fill the textLabel with the relevant text
    // Reminder Section


    cell.reminderLabel.text = filteredReminder[indexPath.row].reminderName

    if filteredReminder[indexPath.row].reminderPriority == "!" {
    let yourImage: UIImage = UIImage(named: "lowpriority")!
    cell.priorityImage.image = yourImage
    }

    else if filteredReminder[indexPath.row].reminderPriority == "!!" {
    let yourImage: UIImage = UIImage(named: "mediumpriority")!
    cell.priorityImage.image = yourImage
    }

    else if filteredReminder[indexPath.row].reminderPriority == "!!!" {
    let yourImage: UIImage = UIImage(named: "highpriority")!
    cell.priorityImage.image = yourImage
    }

    /* I DON'T KNOW WHAT THIS COMPLETION FOR, HOPE IT IS WORKING A/C TO YOUR NEED. */

    // cell.completeButtonAction = { [unowned self] in
    // let reminderCall = reminders[indexPath.row].reminderName
    // let alert = UIAlertController(title: "Complete!", message: "You have completed \(reminderCall).", preferredStyle: .alert)
    // let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
    // alert.addAction(okAction)
    //
    // reminders.remove(at: indexPath.row)
    // self.tableReminders.deleteRows(at: [indexPath], with: .fade)
    // convertAndSaveInDDPath(array: reminders)
    //
    // print("reminder deleted")
    //
    // self.present(alert, animated: true, completion: nil)
    // }
    //


    return cell

    }
  5. 要删除单元格,现在只需要这样做。

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == .delete {

    filteredReminder.remove(at: indexPath.row)
    tableReminders.deleteRows(at: [indexPath], with: .fade)
    // convertAndSaveInDDPath(array: filteredReminder) // UNCOMMENT THIS

    }
    }

关于ios - 从过滤数据崩溃的 TableView 中删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57319951/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com