2011-01-08 28 views
5

Cho đến hôm nay, tôi chưa bao giờ có dịp sử dụng bất cứ điều gì khác ngoài NSWindow như là một NSDraggingDestination. Khi sử dụng một cửa sổ như một điểm đến kéo dài một kích thước phù hợp với tất cả, NSWindow sẽ chuyển các thông điệp đó cho đại biểu của nó, cho phép bạn xử lý các giọt mà không có phân lớp con của NSWindow.Cocoa NSTextField Kéo & Thả Yêu cầu lớp con ... Thật sao?

Các docs nói:

Mặc dù NSDraggingDestination là khai báo là một giao thức không chính thức, các NSWindow và NSView lớp con bạn tạo thông qua các giao thức cần chỉ thực hiện những phương pháp đó là thích hợp. (Các lớp NSWindow và NSView cung cấp các triển khai riêng cho tất cả các phương pháp .) Đối tượng cửa sổ hoặc đại biểu của nó có thể thực hiện các phương thức này; tuy nhiên, triển khai của đại biểu được ưu tiên nếu có các triển khai ở cả hai địa điểm .

Hôm nay, tôi có một cửa sổ có hai NSTextField trên đó và tôi muốn chúng có các hành vi thả khác nhau và tôi không muốn cho phép các giọt khác ở bất kỳ nơi nào khác trong cửa sổ. Cách tôi giải thích các tài liệu, có vẻ như tôi phải phân lớp NSTextField, hoặc làm cho một số trình xử lý thả spaghetti có điều kiện khổng lồ trên đại biểu của cửa sổ nhấn-kiểm tra kéo Location đối với mỗi khung nhìn để chọn các hành vi thả khác nhau cho mỗi trường.

Phương pháp xử lý thả xuống có trụ sở tại NSWindow tập trung dường như sẽ trở nên nguy hiểm trong bất kỳ trường hợp nào bạn có nhiều hơn một số lần xem điểm đến thả nhỏ. Tương tự như vậy, cách tiếp cận subclassing dường như không quan trọng bất kể trường hợp, bởi vì bây giờ mã xử lý thả sống trong một lớp khung nhìn, vì vậy một khi bạn chấp nhận sự sụt giảm, bạn phải đưa ra một số cách để sắp xếp lại dữ liệu bị bỏ lại cho mô hình. Các bindings docs cảnh báo bạn tắt của cố gắng để lái xe bindings bằng cách thiết lập giá trị giao diện người dùng lập trình. Vì vậy, bây giờ bạn đang mắc kẹt làm việc theo cách của bạn trở lại xung quanh đó quá.

Vì vậy, câu hỏi của tôi là: "Thật sao !? Có phải đó là những lựa chọn duy nhất có sẵn không? Hay tôi thiếu thứ gì đó đơn giản ở đây?"

Cảm ơn.

+0

Bạn nên sửa lỗi đánh máy trong tiêu đề câu hỏi của mình (NSTextView! = NSTextField). – NSGod

Trả lời

6

Sau một chút nghiên cứu, có vẻ như "Có, thực sự, hai tùy chọn của bạn là phân lớp NSTextField hoặc sử dụng NSWindowDelegate để xử lý các giọt". Tôi sẽ đi xa hơn và đưa ra tuyên bố rằng cách tốt hơn cho cả hai, đối với các trường hợp vườn, "Tôi muốn nhiều vùng thả trong một cửa sổ duy nhất" là sử dụng phương pháp NSWindowDelegate với các lần kiểm tra lần truy cập, vì bạn tránh vấn đề có mã xử lý thả của bạn ở phía bên xem. Tôi đã kết thúc với draggingUpdated này: Phương pháp trên cửa sổ lớp đại biểu của tôi:

- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender 
{ 
    NSPasteboard *pboard = [sender draggingPasteboard]; 
    NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; 

    if ([pboard.types containsObject: NSFilenamesPboardType] && (sourceDragMask & NSDragOperationCopy)) 
    { 
     NSView* hitView = [sender.draggingDestinationWindow.contentView hitTest: sender.draggingLocation]; 
     if (hitView && (hitView == mSourceTextField || hitView == mDestTextField)) 
     { 
      return NSDragOperationCopy;    
     } 
    } 

    return NSDragOperationNone; 
} 

Rõ ràng có nhiều đến bức tranh toàn cảnh, nhưng hitTest này: Cách tiếp cận dựa trên đã làm việc cho tôi cho đến nay. Tôi nghi ngờ rằng điều này sẽ phức tạp hơn một chút nếu một người đang làm việc với một điều khiển dựa trên nhiều NSCell như một NSTableView hoặc NSOutlineView, nhưng không ngạc nhiên, những người có các phương thức xử lý kéo riêng của họ.

Hy vọng điều này sẽ giúp người khác.

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