[英]How to select the current item to delete it from an array in Swift using Realm
因此,我尝试通过互联网和 StackOverflow 寻找答案,但我不确定要寻找什么,所以答案可能已经共享。 所以我很抱歉,因为我是菜鸟。 但是,我仍然需要帮助。 (请,)我有一个我正在使用的应用程序,其中包含一个充满零件的表格视图,其中包含一个详细信息零件页面,其中提供了零件的详细信息(零件名称、零件编号、描述等)
我在页面末尾有一个删除按钮,当您单击它时,它会询问您是否要删除,您确定吗? 如果用户说是,则该部分将被删除,但删除仅从 tableview 中删除了最后一个项目,即最近添加的项目。 我知道,是因为我调用了以下 function:
func deletePart() {
if let partToDelete = getPartsArray().last {
try! realm.write {
realm.delete(partToDelete)
}
}
用'getPartsArray()。 最后'
我正在尝试查看如何删除表视图中的当前选定部分。 现在,我可以选择顶部的第二部分,如果我单击该部分的删除按钮,它将始终从 tableview 中删除最后一部分。
这是 getPartsArray function 的代码:
func getPartsArray() -> [PartInfo] {
return getAllParts().map { $0 }
}
我(笨拙地)已经尝试过:使用'getPartsArray()。 当前' 显然这不是一回事,哈哈。
我也在想,既然我使用的是 REALM / Mongo DB,我可以通过它的 ID 找到零件吗? 然后删除它? 但我也不确定如何找到当前 select 部件的 id。
任何帮助将非常感激。 谢谢!
编辑:这是我的 TableView 代码:
//
// ViewAllPartsViewController.swift
// PartKart
//
// Created by Kiarra Julien on 10/20/21.
//
import Foundation
import UIKit
class ViewAllPartsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CurrencyFormatter {
private var brain = PartKartBrain()
private var parts = [PartInfo]()
@IBOutlet var tableView: UITableView!
@IBAction func returnHome() {
dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: "DemoTableViewCell", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "DemoTableViewCell")
tableView.delegate = self
tableView.dataSource = self
parts = brain.getPartsArray()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
parts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DemoTableViewCell", for: indexPath) as! DemoTableViewCell
cell.partNameLabel.text = parts[indexPath.row].partName
// Convert string value to double
cell.partCostLabel.text = formatCurrency(value: parts[indexPath.row].partCost)
// String(format: "$%.2f", parts[indexPath.row].partCost)
cell.purchaseDateLabel.text = parts[indexPath.row].purchaseDate
// cell.textLabel?.text = parts[indexPath.row].partName
// cell.textLabel?.numberOfLines = 0countTotalParts()
// cell.textLabel?.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: "showPartDetails", sender: parts[indexPath.row])
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
if let viewcontroller = segue.destination as? PartDetailsViewController {
viewcontroller.part = sender as? PartInfo
}
}
}
这就是我所说的删除部分:
class PartDetailsViewController: UIViewController, CurrencyFormatter {
//Store Information Labels
@IBOutlet weak var storeNameLabel: UILabel!
@IBOutlet weak var storeNumLabel: UILabel!
@IBOutlet weak var storeAddrLabel: UILabel!
//Part Information Labels
@IBOutlet weak var partNameLabel: UILabel!
@IBOutlet weak var partNumLabel: UILabel!
@IBOutlet weak var partDescLabel: UILabel!
@IBOutlet weak var partCostLabel: UILabel!
@IBOutlet weak var partQtyLabel: UILabel!
@IBOutlet weak var purchaseDateLabel: UILabel!
@IBOutlet weak var hasWarrantySwitch: UISwitch!
@IBOutlet weak var warrantyLengthLabel: UILabel!
//Mechanic Information Labels
@IBOutlet weak var mechanicNameLabel: UILabel!
@IBOutlet weak var mechanicNumLabel: UILabel!
@IBOutlet weak var mechanicAddrLabel: UILabel!
@IBOutlet weak var laborCostLabel: UILabel!
@IBOutlet weak var serviceDateLabel: UILabel!
var part: PartInfo?
let brain = PartKartBrain()
@IBAction func deletePartBtn(_ sender: UIButton) {
// Declare Alert message
let dialogMessage = UIAlertController(title: "Confirm", message: "Are you sure you want to delete this part?", preferredStyle: .alert)
// Create OK button with action handler
let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
print("Ok button tapped")
// I CALL DELETE PART RIGHT HEREEE!
self.brain.deletePart()
// delay and then dismiss the page
let delayInSeconds = 0.5
DispatchQueue.main.asyncAfter(deadline: .now() + delayInSeconds) { [unowned self] in
dismiss(animated: true, completion: nil)
}
})
// Create Cancel button with action handlder
let cancel = UIAlertAction(title: "Cancel", style: .cancel) { (action) -> Void in
print("Cancel button tapped")
}
//Add OK and Cancel button to dialog message
dialogMessage.addAction(ok)
dialogMessage.addAction(cancel)
// Present dialog message to user
self.present(dialogMessage, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
title = part?.partName
//Set the Store Info Labels Equal to actual data
storeNameLabel.text = part?.partName
storeNumLabel.text = part?.storeNumber
storeAddrLabel.text = part?.storeAddress // < ---- The address is cut off the screen!
//Set the Part Info Labels Equal to actual data
partNameLabel.text = part?.partName
partNumLabel.text = part?.partNumber
partDescLabel.text = part?.partDescription
if let partCost = part?.partCost {
partCostLabel.text = formatCurrency(value: partCost)
}
if let partQty = part?.partQuantity {
partQtyLabel.text = String(partQty)
}
purchaseDateLabel.text = part?.purchaseDate
//If there's no warranty, display 'N/A' instead
if part?.hasWarranty == true {
hasWarrantySwitch.isOn = true
warrantyLengthLabel.text = part?.warrantyLength
} else {
hasWarrantySwitch.isOn = false
warrantyLengthLabel.text = "N/A"
}
//Set the Mechanic Info Labels Equal to actual data
mechanicNameLabel.text = part?.mechanicName
mechanicNumLabel.text = part?.mechanicNumber
mechanicAddrLabel.text = part?.mechanicAddress
//laborCostLabel.text = part?.laborCost
if let laborCost = part?.laborCost {
laborCostLabel.text = formatCurrency(value: laborCost)
}
serviceDateLabel.text = part?.serviceDate
}
}
让我把 state 问题回给你
“如何从我的表格视图中删除选定的行”?
如果这是问题,让我们提供一个简单的答案
首先,在使用 Realm 时不要这样做
return getAllParts().map { $0 }
Realm 对象被延迟加载到结果 object 中。 一旦您针对高级别的 function (例如 map、reduce 等)运行它们(将它们存储在数组中),它们都会被加载到 memory 中,如果您拥有一个庞大的数据集,那么您将淹没设备。 此外,如果您有排序等,您的对象将与底层 Realm 数据不同步。
您最好的选择是利用 Realm 结果作为您的 tableView 数据源 - 它的行为很像数组。
所以这是一个viewController class,它有一个部分Results object作为tableView数据源
class InStockVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
var partsNotificationToken: NotificationToken!
var partsResults: Results<PartsClass>! //the tableView dataSource
假设用户点击或选择第 2 行,然后点击或单击“删除”
//pseudocode
let selectedRow = tableView.selectedRow
let part = partResults[selectedRow]
try! realm.write {
realm.delete(part)
}
上面的代码确定选择了表中的哪一行,从结果中获取 object 部分,然后告诉 Realm 删除它。
一旦从 Realm 中删除 object,partsResults object 就会反映该更改,并且自动删除 ZA8CFDE6331BD59EB66AC96F891111。 您唯一需要做的就是在 UI 中反映这种变化。
有很多方法可以处理动画等,但为了简单起见,让我们重新加载 tableView,这样删除的行就不再显示了。
注意在上面的代码中,还有一个var partsNotificationToken: NotificationToken!
,该令牌是结果 object 的观察者 - 当基础数据中的某些内容发生更改时,结果 object 也会发生变化,并且通知令牌会触发观察者操作来处理该更改。 这是一个示例观察者
self.partsNotificationToken = self.partsResults.observe { changes in
switch changes {
case .initial:
self.tableView.reloadData() //update the tableview after data is initially loaded
case .update(_, _, _, _):
self.tableView.reloadData() //update the tableView after changes
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.