本文介绍了通过滑动从 NSTableview 中删除行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过滑动功能从我的 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 中删除行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 06:11