2017-06-11 20 views
5

Tôi làm việc nhanh với 3 đối với osx và tôi đang tìm kiếm giải pháp kéo và thả giữa hai NSTableViews trong các bộ điều khiển chế độ xem khác nhau.kéo và thả không ổn định với chế độ xem ô tùy chỉnh

Tôi có một giải pháp làm việc đơn giản cho trường hợp đó, mỗi lần xem bảng chỉ có một cột, không có dạng xem ô và giá trị chuỗi tùy chỉnh.

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 
    } 

} 

Nhưng bây giờ tôi cần một giải pháp đối với trường hợp sau đây:

  • SourceTableView> một cột> xem tế bào tùy chỉnh> val ues mỗi tế bào: firstName, secondName
  • TargetTableView> ba cột> xem tế bào tùy chỉnh> giá trị mỗi tế bào: firstName, secondName, Tuổi

các giá trị tôi nhận được thông qua dữ liệu lõi:

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 { } 
} 

Nhưng giải pháp trên của tôi không hoạt động với "trường hợp mong muốn" mới của tôi

CẬP NHẬT Ví dụ: I sửa đổi SourceTabelView của tôi như thế này:

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 
    } 
} 

Nó hoạt động tốt, nhưng nếu tôi kéo hàng với giá trị "Max" => treo ứng dụng của tôi với lỗi này:

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. Câu trả lời dưới đây có giải quyết được vấn đề không? nếu có, xin vui lòng chấp nhận nó như là câu trả lời. –

Trả lời

3

Lý do ngoại hình tai nạn giống như, thời gian chạy Swift không thể tìm thấy encodeWithCoder cho loại cấu trúc của bạn.

Bạn có thể cần triển khai encodeWithCoder. StructData struct của bạn phải phù hợp với encodeWithCoder.

hãy có một cái nhìn tại liên kết sau đây về cách làm tương tự

Example-1 Example-2 Example-3

+0

có lẽ nó giúp. nhưng không thể nhận ra nó trong dự án của tôi :( – Ghost108

+0

Khó khăn ở đâu? –

Các vấn đề liên quan