2011-12-31 16 views
6

में खींचकर तालिका पंक्तियों को पुनर्व्यवस्थित करना मुझे अपने ऐप में पंक्तियों को पुनर्व्यवस्थित करने के लिए नई शेर कार्यक्षमता का उपयोग करने में समस्या हो रही है। मैं पंक्ति अनुक्रमणिका को संग्रहीत करने के लिए outlineView:pasteboardWriterForItem: का उपयोग कर रहा हूं ताकि जब मैं ड्रॉप को मान्य/स्वीकार कर दूं तो मैं उन्हें बाद में एक्सेस कर सकता हूं। मैं एक नया NSPasteboardItem वापस जाने के लिए बनाते हैं, और इतनी के रूप में पंक्ति संख्या संग्रहीत करने का प्रयास कर रहा हूँ:शेर

[pbItem setData: [NSKeyedArchiver archivedDataWithRootObject: [NSNumber numberWithInteger: [fTableView rowForItem: item]]] 
                forType: TABLE_VIEW_DATA_TYPE]; 

TABLE_VIEW_DATA_TYPE मैं खींच पेस्टबोर्ड में अपने कस्टम डेटा भेद करने के लिए उपयोग कर रहा हूँ एक कस्टम स्ट्रिंग है। मैं इन पंक्तियों को खींचने के बाहर इसका उपयोग नहीं करता हूं।

जब खींचें का प्रयास कर रहा है, मैं कंसोल में प्राप्त करते हैं: 'TableViewDataType' is not a valid UTI string. Cannot set data for an invalid UTI.

बेशक

मैं से कुछ का उपयोग कर सकता है pasteboards के लिए निर्मित यूटीआई, लेकिन उनमें से कोई लागू (और उन्हें प्रयोग खींचें स्वीकार करने के लिए अन्य खींच लेता है का कारण बनता है पंक्तियों की तुलना में, जो इसे नहीं करना चाहिए)। क्या मुझे कुछ याद आ रहा है, एक कस्टम यूटीआई को सिर्फ खींचने के लिए परिभाषित करने के तरीके (इसे "वास्तविक" यूटीआई के बिना, क्योंकि मेरे पास आंतरिक ड्रैगिंग के बाहर इसका कोई उपयोग नहीं है, इसलिए यह सार्वजनिक नहीं होना चाहिए)।

किसी भी मदद के लिए धन्यवाद!

उत्तर

2

एक वेनिला NSPasteboardItem का उपयोग करने के बजाय, आपको एक कस्टम ऑब्जेक्ट बनाना चाहिए जो NSPasteboardWriting प्रोटोकॉल के अनुरूप है।

अपनी कस्टम ऑब्जेक्ट में, आप अपने पेस्टबोर्ड आइटम का समर्थन करने वाले कस्टम यूटीआई की एक सूची वापस करने के लिए writableTypesForPasteboard: लागू कर सकते हैं। जब आप पेस्टबोर्ड मांगते हैं तो उचित कस्टम यूटीआई के लिए अपनी ऑब्जेक्ट का एक प्लास्ट प्रतिनिधित्व वापस करने के लिए आप pasteboardPropertyListForType: लागू करते हैं।

आप +propertyListWithData:options:format:error:NSPropertyListSerialization की विधि का उपयोग करके मनमानी डेटा से एक प्लेलिस्ट बना सकते हैं।

फिर आप अपने कस्टम ऑब्जेक्ट का उदाहरण लौटने के लिए अपने तालिका दृश्य डेटा स्रोत में tableView:pasteboardWriterForRow: ओवरराइड करेंगे।

+1

धन्यवाद, मैं प्रतिक्रिया की सराहना करता हूं। मैं अभी भी वास्तव में हैरान हूं कि पुन: व्यवस्थित पंक्तियों का ट्रैक रखने के लिए यह बहुत जटिल है। – livings124

+0

मैंने एक ऑब्जेक्ट लागू किया जो 'NSPasteboardWriting' के अनुरूप है जो 'writableTypesForPasteboard:' के लिए मेरी कस्टम यूटीआई देता है, लेकिन मुझे मिल रहा है: _'TableViewDataType 'मान्य यूटीआई स्ट्रिंग नहीं है। क्लास TableViewDragNode._ – livings124

+0

में लौटाए गए प्रकार के रूप में अमान्य यूटीआई का उपयोग नहीं कर सकता: यदि ऐसा है तो मुझे नहीं लगता कि आपके पास आपके Info.plist में आपके ड्रैग ऑपरेशंस के लिए एक कस्टम यूटीआई घोषित करने के अलावा कोई विकल्प नहीं है। मैं मानता हूं, यह एक अजीब सीमा प्रतीत होता है। मुझे विश्वास नहीं है कि रनटाइम पर यूटीआई को परिभाषित करना संभव है, इसे Info.plist में हार्ड-कोड किया जाना चाहिए। –

5

एक और तकनीक जिसका आप उपयोग कर सकते हैं वह केवल उन ऑब्जेक्ट्स के इंडेक्स को स्टोर करना है जो आप एक आवृत्ति चर में खींच रहे हैं। पेस्टबोर्ड पर सबकुछ डालना तब तक सख्ती से जरूरी नहीं है जब तक कि आप किसी अन्य ऐप से आइटम स्वीकार नहीं कर रहे हों या इसके विपरीत।

  1. जागने में FromNib, NSStringPboardType के लिए पंजीकरण करें।
  2. में ... पेस्टबोर्डवाइटरफॉररो, वापसी [एनएसएसटींग स्ट्रिंग]।
  3. में ... ड्रैगिंग सत्र: willBegin ..., अपने इंस्टेंस वैरिएबल को उन इंडेक्स पर सेट करें जिन्हें आप ट्रैक करना चाहते हैं।
  4. मान्य करने के लिए, एनएसडीआरएजीऑपरेशन वापस करें यदि आपका इंस्टेंस वैरिएबल शून्य है या दृश्य आपका नहीं है।
  5. में ... ड्रैगिंग सत्र: समाप्त ..., अपने इंस्टेंस चर को बाहर निकालें।

आशा है कि मदद करता है ... मैं तालिका दृश्य के लिए तकनीक का उपयोग कर रहा हूं, लेकिन यह एक रूपरेखा दृश्य के लिए लगभग समान होना चाहिए।

6

मुझे इसी तरह की आवश्यकताएं थीं, सिवाय इसके कि मेरे पास ऑब्जेक्ट्स का ग्रिड था जिसे मैं चयनित ऑब्जेक्ट को नए स्थान पर खींचकर पुनर्व्यवस्थित करना चाहता था।ऐसा करने के कई तरीके हैं, जिसमें कस्टम ऑब्जेक्ट बनाने और NSPasteboardWriting और NSPasteboardReading प्रोटोकॉल को कार्यान्वित करने, और प्रोटोकॉल को लागू करने के कई तरीके हैं, यदि आप NSPasteboardReadingAsKeyedArchive के रूप में डेटा पढ़ रहे होंगे), लेकिन ऐसा लगता है कि यह उन वस्तुओं को खींचने के लिए अधिक है जो आंतरिक हैं आवेदन।

मैंने कस्टम यूटीआई प्रकार के साथ एक रैपर के रूप में NSPasteboardItem का उपयोग करना शामिल किया है (यह पहले से ही NSPasteboardWriting और NSPasteboardReading प्रोटोकॉल लागू करता है)।

#define kUTIMyCustomType @“com.mycompany.MyApp.MyCustomType”

यह 'com.domain.MyApp' प्रारूप में परिभाषित करने की आवश्यकता अन्यथा आप फार्म की त्रुटियां मिलेंगी: "XXX एक वैध यूटीआई स्ट्रिंग नहीं है सबसे पहले एक कस्टम यूटीआई प्रकार की घोषणा। अमान्य यूटीआई के लिए डेटा सेट नहीं कर सकता। "ऐप्पल ने इसे अपने दस्तावेज में उल्लेख किया है।

फिर आपको इस कस्टम यूटीआई प्रकार को उस दृश्य में पंजीकृत करना होगा जिसमें आपका ड्रैगिंग होगा। यह रनटाइम पर किया जा सकता है, और किसी भी .plist जोड़ों की आवश्यकता नहीं है। अपने दृश्य के init विधि में निम्नलिखित जोड़ें:

[self registerForDraggedTypes:[NSArray arrayWithObjects:(NSString *)kUTIMyCustomType, nil]]; 

अब, यह सुनिश्चित करें कि प्रतिनिधि इस दृश्य के लिए सेट किया गया है, और प्रतिनिधि वस्तु को लागू करता है की आवश्यकता NSDraggingSource और NSDraggingDestination प्रोटोकॉल तरीकों। यह आपको एमवीसी डिज़ाइन पैटर्न को तोड़ने से रोकने के लिए अनुमति देगा, नामित नियंत्रक ऑब्जेक्ट को पेस्टबोर्ड पर डेटा रखने में संभाल करने की अनुमति देकर, जिसमें संभावित रूप से मॉडल डेटा (यानी, इंडेक्स) क्वेरी करना शामिल होगा।

विशेष रूप से, खींचने पर रखने वस्तुओं की अनुक्रमणिका पेस्टबोर्ड के लिए जब खींचकर ले जाया जा करने के लिए अपने सूचकांक आंकड़ों के NSPasteboardItem रैपर के रूप में शुरू होता है:

- (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]; 
} 

और जब खींच आपरेशन पूरा करता है, घसीटा सूचकांक को पढ़ने के लिए NSPasteboardItem डेटा:

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