NSTableview-拖放分为两个类和控制器 [英] NSTableview - Drag and Drop split into two classes and controllers

查看:73
本文介绍了NSTableview-拖放分为两个类和控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了这个有用的教程,可以使用nstabelview实现拖放: https://drive.google.com/open?id=0B8PBtMQt9GdONzV3emZGQWUtdmM

i found this helpfully tutorial for realize drag an drop with nstabelview: https://drive.google.com/open?id=0B8PBtMQt9GdONzV3emZGQWUtdmM

这很好.

但是我想用拆分视图将两个表视图拆分为不同的视图控制器和类:

but i would like to split both table views into differente view controllers and classes with a split view:

一个拆分视图控制器:

  • 项目1:带有源nstableview(SourceTableView.class)的Viewcontroller
  • 项目2:具有目标nstableview(TargetTableView.class)的ViewController

我如何在这个项目中做到这一点? 我知道如何在情节提要中创建拆分视图控制器. 但是我不知道,如果我有两个不同的类,则SourceTableView.class类的iBoutlet SourceTabelView如何分配TargetTableView.class类的iBoutlet TargetTableView

how can i do this with this project? i know how can i create a split view controller in storyboard. but i dont know, if i have two different classes, how the iBoutlet SourceTabelView of class SourceTableView.class assign the iBoutlet TargetTableView of class TargetTableView.class

更新

var person = [Person]()

NSManagedObject.class

import Foundation
import CoreData

@objc(Person)
public class Person: NSManagedObject {
    @NSManaged public var firstName: String
    @NSManaged public var secondName: String
}

推荐答案

在拆分视图内的两个表视图之间拖放的示例.在一个表格视图中拖动并选择多个即可.按住Option键拖动副本.

Example of drag and drop between two table views inside a split view. Dragging inside one table view and multiple selection will work. Hold the Option key to drag a copy.

每个表视图的数据源是拆分视图内部的视图控制器.每个表视图都有自己的视图控制器,每个视图控制器控制一个表视图.两个视图控制器是相同的NSViewController子类:

The datasource of each table view is the view controller inside the split view. Each table view has its own view controller and each view controller controls one table view. Both view controllers are the same NSViewController subclass:

class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {

    @IBOutlet weak var myTableView: NSTableView!
    var dataArray: NSMutableArray = ["John Doe", "Jane Doe", "Mary Jane"]

    override func viewDidLoad() {
        super.viewDidLoad()
        myTableView.register(forDraggedTypes: ["com.yoursite.yourproject.yourstringstype"])
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    // NSTableViewDataSource data methods

    func numberOfRows(in tableView: NSTableView) -> Int {
        return dataArray.count
    }

    func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
        return dataArray[row] as AnyObject!;
    }

    // NSTableViewDataSource drag methods

    func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
        // the dragging destination needs the strings of the rows to add to its own data,
        // we, the dragging source, need the indexes of the rows to remove the dropped rows.
        pboard.declareTypes(["com.yoursite.yourproject.yourstringstype", "com.yoursite.yourproject.yourindexestype"],
            owner: nil)
        pboard.setData(NSKeyedArchiver.archivedData(withRootObject: (dataArray as NSArray).objects(at:rowIndexes as IndexSet)), forType: "com.yoursite.yourproject.yourstringstype")
        pboard.setData(NSKeyedArchiver.archivedData(withRootObject: rowIndexes), forType: "com.yoursite.yourproject.yourindexestype")
        return true
    }

    func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession,
            endedAt screenPoint: NSPoint, operation: NSDragOperation) {
        // remove the dragged rows if the rows are dragged to the trash or were moved to somewhere else.
        var removeRows = false
        if operation == .delete {
            // trash
            removeRows = true
        } else if operation == .move {
            // check if the point where the rows were dropped is inside our table view.
            let windowRect = tableView.convert(tableView.bounds, to: nil)
            let screenRect = view.window!.convertToScreen(windowRect)
            if !NSPointInRect(screenPoint, screenRect) {
                removeRows = true
            }
        }
        if removeRows {
            // remove the rows, the indexes are on the pasteboard
            let data = session.draggingPasteboard.data(forType: "com.yoursite.yourproject.yourindexestype")!
            let rowIndexes = NSKeyedUnarchiver.unarchiveObject(with: data) as! NSIndexSet
            (dataArray as NSMutableArray).removeObjects(at: rowIndexes as IndexSet)
            tableView.reloadData()
        }
    }

    // NSTableViewDataSource drop methods

    func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, 
            proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation {
        // only accept drop above rows, not on rows.
        if dropOperation == .above {
            // return move if the dragging source allows move
            if info.draggingSourceOperationMask().contains(.move) {
                return .move
            }
            // return copy if the dragging source allows copy
            if info.draggingSourceOperationMask().contains(.copy) {
                return .copy
            }
        }
        return []
    }

    func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int,
            dropOperation: NSTableViewDropOperation) -> Bool {
        // if the rows were moved inside the same table view we do a reorder
        var dropRow = row
        if info.draggingSource() as AnyObject === myTableView as AnyObject &&
            info.draggingSourceOperationMask().contains(.move) {
            // remove the rows from their old position
            let data = info.draggingPasteboard().data(forType: "com.yoursite.yourproject.yourindexestype")!
            let rowIndexes = NSKeyedUnarchiver.unarchiveObject(with: data) as! NSIndexSet
            (dataArray as NSMutableArray).removeObjects(at: rowIndexes as IndexSet)
            // recalculate the row of the drop
            dropRow -= rowIndexes.countOfIndexes(in: NSMakeRange(0, dropRow))
        }
        // insert the dragged rows
        let data = info.draggingPasteboard().data(forType: "com.yoursite.yourproject.yourstringstype")!
        let draggedStrings = NSKeyedUnarchiver.unarchiveObject(with: data) as! [Any]
        dataArray.insert(draggedStrings, at:IndexSet(integersIn:dropRow..<(dropRow + draggedStrings.count)))
        tableView.reloadData()
        return true
    }

}

要拖到垃圾箱,请子类NSTableView并覆盖:

To make dragging to the trash work, subclass NSTableView and override:

override func draggingSession(_ session: NSDraggingSession, sourceOperationMaskFor
        context: NSDraggingContext) -> NSDragOperation {
    let test = super.draggingSession(session, sourceOperationMaskFor: context)
    Swift.print("sourceOperationMaskFor \(test)")
    switch context {
        case .withinApplication:
            return [.move, .copy]
        case .outsideApplication:
            return [.delete]
    }
}

p.s.我不熟悉Swift,并且在数组和索引集方面遇到了一些麻烦,所以我使用了NSMutableArrayNSIndexSet.

p.s. I'm not familiar with Swift and had some trouble with arrays and indexsets so I used NSMutableArray and NSIndexSet.

这篇关于NSTableview-拖放分为两个类和控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆