问题描述
我正在尝试通过滑动功能从我的 NStableView 中删除一行.我正在使用 macOS 10.13 和 swift 4,并且对 swift 编码非常陌生.
我尝试遵循:
I am trying to remove a row from my NStableView by swipe function. I am using macOS 10.13 and swift 4 and pretty new to swift coding.
I tried to follow: Implementing NSTableViewRowAction using Swift but it did not work for me.
And this is how I implement it:
public func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableView.RowActionEdge) -> [NSTableViewRowAction] {
// left swipe
if edge == .trailing {
let deleteAction = NSTableViewRowAction(style: .destructive, title: "Delete", handler: { (rowAction, row) in
// action code
List_Symbol.remove(at: row)
List_Price.remove(at: row)
List_Procent.remove(at: row)
List_Volume.remove(at: row)
})
deleteAction.backgroundColor = NSColor.red
return [deleteAction]
}
let archiveAction = NSTableViewRowAction(style: .regular, title: "Archive", handler: { (rowAction, row) in
// action code
})
return [archiveAction]
}
Any other suggestion how to delete row in NSTableView by swiping?
The Whole code:
import Cocoa
import Alamofire
var List_Symbol = ["AAPL"]
var List_Price = [10.0]
var List_Procent = [1.0]
var List_Volume = [100]
class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
@IBOutlet weak var tableView: NSTableView!
@IBOutlet weak var input: NSTextField!
@IBAction func additem(_ sender: Any) {
if (input.stringValue != ""){
var Stock = StockInformation(symbol: input.stringValue)
Stock.GetStockInformation {
List_Symbol.append(Stock.Symbol)
List_Price.append(Stock.Price)
List_Procent.append(Stock.Percent)
List_Volume.append(Stock.Volume)
self.tableView.reloadData()
}
input.stringValue = ""
}
self.tableView.reloadData()
}
public func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableView.RowActionEdge) -> [NSTableViewRowAction] {
// left swipe
if edge == .trailing {
let deleteAction = NSTableViewRowAction(style: .destructive, title: "Delete", handler: { (rowAction, row) in
// action code
List_Symbol.remove(at: row)
List_Price.remove(at: row)
List_Procent.remove(at: row)
List_Volume.remove(at: row)
tableView.removeRows(at: IndexSet(integer: row), withAnimation: .effectFade)
})
deleteAction.backgroundColor = NSColor.red
return [deleteAction]
}
let archiveAction = NSTableViewRowAction(style: .regular, title: "Archive", handler: { (rowAction, row) in
// action code
})
return [archiveAction]
}
override func viewDidAppear() {
tableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
}
func numberOfRows(in tableView: NSTableView) -> Int{
return List_Symbol.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any?{
var identifierStr = tableColumn!.identifier
if (identifierStr.rawValue == "StockNameCellID"){
return List_Symbol[row]
}else if (identifierStr.rawValue == "PriceCellID"){
return List_Price[row]
}else if (identifierStr.rawValue == "PercentCellID"){
return List_Procent[row]
}else if (identifierStr.rawValue == "VolumeCellID"){
return List_Volume[row]
}
tableView.reloadData()
return nil
}
}
Don't use multiple arrays as data source, that's horrible.
In macOS you can replace a lot of boilerplate code with Cocoa Bindings
• Use a class inherited from NSObject
as data source
@objcMembers
class Stock : NSObject {
dynamic var symbol : String
dynamic var price : Double
dynamic var procent : Double
dynamic var volume : Int
init(symbol : String, price : Double, procent : Double, volume : Int) {
self.symbol = symbol
self.price = price
self.procent = procent
self.volume = volume
}
}
• Declare the data source array within the view controller
@objc var stocks = [Stock]()
• In additem
create a new Stock
item, rather then reloading the table view insert only the row with a smart animation
@IBAction func additem(_ sender: Any) {
if !input.stringValue.isEmpty {
let stock = StockInformation(symbol: input.stringValue)
stock.GetStockInformation {
let newStock = Stock(symbol: stock.Symbol, price: stock.Price, procent: stock.Percent, volume: stock.Volume)
let insertionIndex = IndexSet(integer: stocks.count)
self.stocks.append(newStock)
self.tableView.insertRows(at: insertionIndex, withAnimation: .effectGap)
self.input.stringValue = ""
}
}
}
• objectValueFor
and numberOfRows
are only one line respectively
func numberOfRows(in tableView: NSTableView) -> Int{
return stocks.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
return stocks[row]
}
• The delete
action is
public func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableView.RowActionEdge) -> [NSTableViewRowAction] {
print("swipe")
// left swipe
if edge == .trailing {
let deleteAction = NSTableViewRowAction(style: .destructive, title: "Delete", handler: { (rowAction, row) in
// action code
self.stocks.remove(at: row)
tableView.removeRows(at: IndexSet(integer: row), withAnimation: .effectFade)
})
deleteAction.backgroundColor = NSColor.red
return [deleteAction]
}
}
• In Interface Builder connect datasource and delegate of the table view to the view controller. Further press (Bindings Inspector), then select each Table View Cell
(the NSTextField
not NSTextFieldCell
and not Table Cell View
!) and bind the Value
to Table Cell View
and Model Key Path
to the corresponding property (objectValue.symbol
, objectValue.price
etc.)
You can even use more Cocoa Bindings
by binding the content
of the table view to the stocks
array. Then you can get rid of the datasource and its methods.
这篇关于通过滑动从 NSTableview 中删除行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!