Remove row from NSTableview by swiping

佐手、 提交于 2021-02-07 10:39:13

问题


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
}

}


回答1:


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 ⌥⌘7 (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.



来源:https://stackoverflow.com/questions/51692877/remove-row-from-nstableview-by-swiping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!