2017-06-11 115 views
5

Osx için 3 hızlı çalışıyorum ve farklı görünüm denetleyicilerindeki iki NSTableView arasında sürükle ve bırak çözümünü arıyorum.nstableview Özel hücre görünümleriyle sürükleyip bırakın

Durum için basit bir çalışma çözümüm var; her bir tablo görünümünde yalnızca bir sütun, özel hücre görünümü ve dize değerleri yoktur.

SourceTableView

import Cocoa 

class SourceTableView: NSViewController, NSTableViewDelegate, NSTableViewDataSource { 

    @IBOutlet weak var leftTableView: NSTableView! 
    var dataArray: NSMutableArray = ["Item 1","Item 2","Item 3"] 
    let pbStringType = "NSPasteBoardStringType" 
    let pbIndexType = "NSPasteBoardIndexType" 


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

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


    func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool { 
     let data = (dataArray as NSArray).objects(at:rowIndexes as IndexSet) 
     pboard.declareTypes([pbStringType, pbIndexType], owner: nil) 
     pboard.setData(NSKeyedArchiver.archivedData(withRootObject: data), forType: pbStringType) 
     pboard.setData(NSKeyedArchiver.archivedData(withRootObject: rowIndexes), forType: pbIndexType) 
     return true 
    } 
} 

TargetTableView

import Cocoa 

class TargetVC2: NSViewController, NSTableViewDelegate, NSTableViewDataSource { 

    @IBOutlet weak var rightTableView: NSTableView! 
    var dataArray: NSMutableArray = ["Item 5", "Item 6", "Item 7"] 
    let pbStringType = "NSPasteBoardStringType" 
    let pbIndexType = "NSPasteBoardIndexType" 


    override func viewDidLoad() { 
     super.viewDidLoad() 
     rightTableView.register(forDraggedTypes: [pbStringType]) 
    } 


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

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



    func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool { 
     let data = dataArray.objects(at:rowIndexes as IndexSet) 
     pboard.declareTypes([pbStringType, pbIndexType], owner: nil) 
     pboard.setData(NSKeyedArchiver.archivedData(withRootObject: data), forType: pbStringType) 
     pboard.setData(NSKeyedArchiver.archivedData(withRootObject: rowIndexes), forType: pbIndexType) 
     return true 
    } 




    func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation { 

     if dropOperation == .above { 
      return .move 
     } 
     return [] 
    } 





    func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableViewDropOperation) -> Bool { 

     var dropRow = row 
     if info.draggingSource() as! NSTableView == rightTableView && tableView == rightTableView && dropOperation == .above { 
      let data = info.draggingPasteboard().data(forType: pbIndexType)! 
      let rowIndexes = NSKeyedUnarchiver.unarchiveObject(with: data) as! NSIndexSet 
      dataArray.removeObjects(at: rowIndexes as IndexSet) 
      dropRow -= rowIndexes.countOfIndexes(in: NSMakeRange(0, dropRow)) 
     } 

     let data = info.draggingPasteboard().data(forType: pbStringType)! 
     let draggedStrings = NSKeyedUnarchiver.unarchiveObject(with: data) as! [Any] 
     dataArray.insert(draggedStrings, at:IndexSet(integersIn:dropRow..<(dropRow + draggedStrings.count))) 
     rightTableView.reloadData() 
     return true 
    } 

} 

Ama şimdi şu durum için bir çözüm gerekir:

  • SourceTableView> bir sütun> özel hücre görünümü> val Hücre başına erler,: ad, secondName
  • TargetTableView> üç sütun> hücre başına özel hücre görünüşüdür> değerleri: ad, secondName, Yaş

Çekirdek veri yolu ile elde değerler:

func requestValues() { 
    var values= [Person]() 
    let appdelegate = NSApplication.shared().delegate as! AppDelegate 
    let context = appdelegate.persistentContainer.viewContext 
    let request = NSFetchRequest<Person>(entityName: "Person") 

    do { 
     values = try context.fetch(request) 
     SourceTableView.reloadData() 
    } catch { } 
} 
Ama yukarıda benim çözüm benim yeni "dilek senaryosu"

GÜNCELLEME Örneğin ile

çalışmıyor: Ben Böyle modifiye benim SourceTabelView:

import Cocoa 

struct structData { 
    var firstname:String 
    var secondname:String 
} 

class SourceVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource { 

    @IBOutlet weak var leftTableView: NSTableView! 
    var people = [structData]() 
    let pbStringType = "NSPasteBoardStringType" 
    let pbIndexType = "NSPasteBoardIndexType" 

    override func viewDidLoad() { 
     people.append(structData(firstname:"Max",secondname:"Mustermann")) 
    } 


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

    func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? { 
     return people[row].firstname 
    } 


    func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool { 
     let data = (people as NSArray).objects(at:rowIndexes as IndexSet) 
     pboard.declareTypes([pbStringType, pbIndexType], owner: nil) 
     pboard.setData(NSKeyedArchiver.archivedData(withRootObject: data), forType: pbStringType) 
     pboard.setData(NSKeyedArchiver.archivedData(withRootObject: rowIndexes), forType: pbIndexType) 
     return true 
    } 
} 

Düzgün çalışır, ama değeri ile satır sürüklerseniz bu hata ile "Max" => benim uygulama kilitleniyor: kilitlenme görünüşleri için

2017-06-12 07:51:09.096744+0200 TableView-DragDrop[10315:1489730] -[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x6080000910d0 
2017-06-12 07:51:09.100198+0200 TableView-DragDrop[10315:1489730] [General] -[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x6080000910d0 
2017-06-12 07:51:09.129238+0200 TableView-DragDrop[10315:1489730] [General] (
    0 CoreFoundation      0x00007fffaf4d657b __exceptionPreprocess + 171 
    1 libobjc.A.dylib      0x00007fffc489a1da objc_exception_throw + 48 
    2 CoreFoundation      0x00007fffaf556f14 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132 
    3 CoreFoundation      0x00007fffaf449c93 ___forwarding___ + 1059 
    4 CoreFoundation      0x00007fffaf4497e8 _CF_forwarding_prep_0 + 120 
    5 Foundation       0x00007fffb0ed695a _encodeObject + 1241 
    6 Foundation       0x00007fffb0ed7f0c -[NSKeyedArchiver _encodeArrayOfObjects:forKey:] + 460 
    7 Foundation       0x00007fffb0ed695a _encodeObject + 1241 
    8 Foundation       0x00007fffb0f12492 +[NSKeyedArchiver archivedDataWithRootObject:] + 156 
    9 TableView-DragDrop     0x00000001000029a3 _TFC18TableView_DragDrop8SourceVC9tableViewfTCSo11NSTableView13writeRowsWithV10Foundation8IndexSet2toCSo12NSPasteboard_Sb + 915 
    10 TableView-DragDrop     0x0000000100002e5c _TToFC18TableView_DragDrop8SourceVC9tableViewfTCSo11NSTableView13writeRowsWithV10Foundation8IndexSet2toCSo12NSPasteboard_Sb + 108 
    11 AppKit        0x00007fffad6fc109 -[NSTableView _sendDataSourceWriteDragDataWithIndexes:toPasteboard:] + 102 
    12 AppKit        0x00007fffad6fcd06 -[NSTableView _performClassicDragOfIndexes:hitRow:event:] + 180 
    13 AppKit        0x00007fffad21e7b5 -[NSTableView _performDragFromMouseDown:] + 468 
    14 AppKit        0x00007fffad21cadf -[NSTableView mouseDown:] + 735 
    15 AppKit        0x00007fffad84024f -[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:] + 6341 
    16 AppKit        0x00007fffad83ca6c -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 1942 
    17 AppKit        0x00007fffad83bf0a -[NSWindow(NSEventRouting) sendEvent:] + 541 
    18 AppKit        0x00007fffad6c0681 -[NSApplication(NSEvent) sendEvent:] + 1145 
    19 AppKit        0x00007fffacf3b427 -[NSApplication run] + 1002 
    20 AppKit        0x00007fffacf05e0e NSApplicationMain + 1237 
    21 TableView-DragDrop     0x000000010000444d main + 13 
    22 libdyld.dylib      0x00007fffc517b235 start + 1 
    23 ???         0x0000000000000003 0x0 + 3 
) 
2017-06-12 07:51:09.148230+0200 TableView-DragDrop[10315:1489730] *** -[NSKeyedArchiver dealloc]: warning: NSKeyedArchiver deallocated without having had -finishEncoding called on it. 
+0

hey nasıl yapılacağına ilişkin aşağıdaki bağlantılardan bir göz atın. Aşağıdaki cevap sorunu çözdü mü? eğer evet ise, lütfen cevap olarak kabul edin. –

cevap

3

nedeni Gibi, Swift çalışma zamanı yapı türünüz için encodeWithCoder bulamıyor.

encodeWithCoder programını uygulamanız gerekebilir. StructData yapınız encodeWithCoder ile uyumlu olmalıdır.

aynı

Example-1 Example-2 Example-3

+0

belki de yardımcı olur. ama benim projemde fark edemiyorum :( – Ghost108

+0

Zorluk nerede? –