我正在尝试通过滑动功能从NStableView中删除一行。我使用的是macOS 10.13和Swift 4,并且是Swift编码的新手。
我尝试遵循:Implementing NSTableViewRowAction using Swift,但它对我不起作用。
这就是我的实现方式:
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]
}
还有其他建议如何通过滑动在NSTableView中删除行吗?
整个代码:
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
}
}
答案 0 :(得分:1)
不要使用多个数组作为数据源,这太可怕了。
在macOS中,您可以用Cocoa绑定替换很多样板代码
•使用从public partial class multipleexcelimport : System.Web.UI.Page
{
protected void importfile()
{
String MyConString = "SERVER=localhost;" + "DATABASE=mysql_testing;" + "UID=root;" + "PASSWORD=tammy;SslMode=none";
if (this.uploadfile.HasFile)
{
string[] segments = fn.Split('.');
string fileExt = segments[segments.Length - 1];
if (fileExt != "xlsx")
{
showMessage("輸入錯誤", "請上傳正確檔案xlsx");
return;
}
foreach (var file in uploadfile.PostedFiles)
{
var fn = file.FileName;
string newfileName = DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + fn;
string filepath = Server.MapPath(ConfigurationSettings.AppSettings["UPLOAD_FOLDER"]) + newfileName;
this.uploadfile.SaveAs(filepath);
ExcelPackage xlWorkbook = new ExcelPackage(new FileInfo(filepath));
ExcelWorksheet xlRange = xlWorkbook.Workbook.Worksheets[1];
int rowCount = xlRange.Dimension.End.Row;
ExcelWorksheet xlRange2 = xlWorkbook.Workbook.Worksheets[2];
int rowCount2 = xlRange2.Dimension.End.Row;
string sql = "";
string linkid = "";
MySqlConnection conn = null;
MySqlDataAdapter msda = null;
DataSet ds = null;
List<string> FailList = new List<string>();
conn = new MySqlConnection(MyConString);
DateTime dTime = DateTime.Now;
string now_time = dTime.ToString("yyyy-MM-dd HH:mm:ss");
conn.Open();
conn.Close();
using (TransactionScope scope = new TransactionScope())
{
try
{
conn.Open();
//sheet1
for (int i = 2; i <= rowCount; i++)
{
string dates = xlRange.Cells[i, 1].Value.ToString();
sql = "INSERT INTO mysql_testing.excel2 set"
+ " excel = ?dates;"
ds = new DataSet();
msda = new MySqlDataAdapter(sql, conn);
msda.SelectCommand.Parameters.AddWithValue("dates", dates);
}
//sheet2
for (int i = 2; i <= rowCount2; i++)
{
string excel3 = xlRange2.Cells[i, 1].Value.ToString();
sql = "INSERT INTO mysql_testing.excel3 set"
+ " excel3 = ?excel3;" ;
ds = new DataSet();
msda = new MySqlDataAdapter(sql, conn);
msda.SelectCommand.Parameters.AddWithValue("excel3", excel3);
}
showMessage("alert", "success");
scope.Complete();
}
catch (Exception ex)
{
throw ex;
}
finally
{
conn.Close();
}
}
ScriptManager.RegisterStartupScript(this, this.GetType(), "tab", "$('.nav-tabs a[href=\"#massimport\"]').tab('show')", true);
}
}
else
{
showMessage("error", "select file plz");
ScriptManager.RegisterStartupScript(this, this.GetType(), "tab", "$('.nav-tabs a[href=\"#massimport\"]').tab('show')", true);
}
}
public void showMessage(string title, string content)
{
ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('" + content + "');", true);
}
protected void Button1_Click(object sender, EventArgs e)
{
importfile();
}
}
继承的类作为数据源
NSObject
•在视图控制器内声明中的数据源数组
@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
}
}
•在@objc var stocks = [Stock]()
中创建一个新的additem
项目,而不是重新加载表格视图,仅插入带有智能动画的行
Stock
•@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
分别仅是一行
numberOfRows
•func numberOfRows(in tableView: NSTableView) -> Int{
return stocks.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
return stocks[row]
}
操作是
delete
•在Interface Builder中,将数据源和表视图的委托连接到视图控制器。进一步按⌥⌘7(绑定检查器),然后选择每个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]
}
}
(Table View Cell
不 NSTextField
和 not NSTextFieldCell
!并将Table Cell View
绑定到Value
,并将Table Cell View
绑定到相应的属性(Model Key Path
,objectValue.symbol
等)
通过将表视图的objectValue.price
绑定到Cocoa Bindings
数组,甚至可以使用更多content
。然后您可以摆脱数据源及其方法。