Tôi có các yêu cầu tương tự trừ khi tôi có một mạng lưới các đối tượng mà tôi muốn sắp xếp lại bằng cách kéo các đối tượng đã chọn đến vị trí mới.Có một số cách để thực hiện việc này, bao gồm tạo đối tượng tùy chỉnh và triển khai các giao thức NSPasteboardWriting
và NSPasteboardReading
, (và NSCoding
giao thức nếu bạn sẽ đọc dữ liệu dưới dạng NSPasteboardReadingAsKeyedArchive
), nhưng điều này có vẻ là quá mức cần thiết cho việc kéo các đối tượng nằm bên trong ứng dụng.
Điều tôi đã làm liên quan đến việc sử dụng NSPasteboardItem
làm trình bao bọc với loại UTI tùy chỉnh (nó đã triển khai các giao thức NSPasteboardWriting
và NSPasteboardReading
). Đầu tiên khai báo một tùy chỉnh UTI loại:
#define kUTIMyCustomType @“com.mycompany.MyApp.MyCustomType”
này cần phải được xác định trong định dạng ‘com.domain.MyApp’ nếu không bạn sẽ nhận được các lỗi có dạng: “XXX không phải là một chuỗi UTI hợp lệ. Không thể đặt dữ liệu cho một UTI không hợp lệ. ”Apple đề cập đến điều này trong tài liệu của họ.
Sau đó, bạn phải đăng ký loại UTI tùy chỉnh này trong chế độ xem mà việc kéo của bạn sẽ xảy ra. Điều này có thể được thực hiện trong thời gian chạy và không yêu cầu bất kỳ bổ sung nào .plist. Trong phương pháp init xem của bạn thêm dòng sau:
[self registerForDraggedTypes:[NSArray arrayWithObjects:(NSString *)kUTIMyCustomType, nil]];
Bây giờ, hãy chắc chắn rằng các đại biểu được thiết lập cho quan điểm này, và các đối tượng delegate thực hiện các yêu cầu NSDraggingSource
và NSDraggingDestination
phương pháp giao thức. Điều này sẽ cho phép bạn tránh phá vỡ mẫu thiết kế MVC, bằng cách cho phép đối tượng điều khiển được chỉ định xử lý việc đặt dữ liệu trên bảng thông báo có khả năng liên quan đến truy vấn dữ liệu mô hình (tức là, chỉ mục).
Cụ thể, để đặt trên kéo tông các chỉ số của các đối tượng được di chuyển khi kéo bắt đầu như NSPasteboardItem
giấy gói dữ liệu chỉ số của bạn:
- (void) draggingSession:(NSDraggingSession *)session willBeginAtPoint:(NSPoint)screenPoint
{
NSPasteboard * pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
[pboard clearContents];
NSMutableArray * selectedIndexes = [NSMutableArray array];
// Add NSString indexes for dragged items to pasteboard in NSPasteboardItem wrappers.
for (MyModel * myModel in [self selectedObjects])
{
NSPasteboardItem * pasteboardItem = [[[NSPasteboardItem alloc] init] autorelease];
[pasteboardItem setString:[NSString stringWithFormat:@"%@", [myModel index]]
forType:kUTIMyCustomType];
[selectedIndexes addObject:pasteboardItem];
}
[pboard writeObjects:selectedIndexes];
}
Và khi thao tác kéo hoàn tất, để đọc các chỉ số kéo NSPasteboardItem
dữ liệu:
- (BOOL) performDragOperation:(id <NSDraggingInfo>)sender
{
NSPasteboard * pasteboard = [sender draggingPasteboard];
// Check for custom NSPasteboardItem's which wrap our custom object indexes.
NSArray * classArray = [NSArray arrayWithObject:[NSPasteboardItem class]];
NSArray * items = [pasteboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
if (items == nil)
return NO;
// Convert array of NSPasteboardItem's with NSString index reps. to array of NSNumber indexes.
NSMutableArray * indexes = [NSMutableArray array];
for (NSPasteboardItem * item in items)
[indexes addObject:[NSNumber numberWithInteger:[[item stringForType:kUTIMyCustomType] integerValue]]];
//
// Handle dragged indexes…
//
return YES;
}
Cảm ơn, tôi đánh giá cao phản hồi. Tôi vẫn thực sự ngạc nhiên rằng nó rất phức tạp để chỉ theo dõi các hàng được sắp xếp lại. – livings124
Tôi đã triển khai một đối tượng phù hợp với 'NSPasteboardWriting' trả về UTI tùy chỉnh của tôi cho' writableTypesForPasteboard: ', nhưng tôi nhận được: _'TableViewDataType 'không phải là chuỗi UTI hợp lệ. Không thể sử dụng một UTI không hợp lệ như một kiểu được trả về từ -writeableTypesForPasteboard: trong lớp TableViewDragNode._ – livings124
Nếu đó là trường hợp thì tôi không nghĩ bạn có bất kỳ tùy chọn nào khác ngoài việc khai báo một UTI tùy chỉnh cho các hoạt động kéo của bạn trong Info.plist của bạn. Tôi đồng ý, điều này có vẻ là một giới hạn kỳ lạ. Tôi không tin rằng nó có thể xác định một UTI trong thời gian chạy, nó phải được mã hóa cứng trong Info.plist. –