25

मैं जो करना चाहता हूं वह बहुत आसान है। मेरे UITableViewController में, मैं कई NSFetchedResultControllers से डेटा लोड करना चाहता हूं (मेरे पास मेरे डेटा मॉडल में एकाधिक इकाइयां हैं) और तालिका दृश्य में प्रत्येक से डेटा को एक अलग सेक्शन में डाल दें। तो उदाहरण के लिए, पहले NSFetchedResultController से प्राप्त सभी आइटम UITableView में सेक्शन 0 में जाएंगे, दूसरे से प्राप्त आइटम अनुभाग 1, आदि में जाते हैं।कोर डेटा: एकाधिक NSFetchedResultControllers के साथ UITableView

कोर डेटा टेम्पलेट प्रोजेक्ट यह प्रदर्शित नहीं करता है कि कैसे यह करो। सबकुछ (मुख्य रूप से इंडेक्स पथ) को अनुभागों को ध्यान में रखे बिना कोड किया जाता है (डिफ़ॉल्ट टेम्पलेट में कोई अनुभाग नहीं होते हैं) और सब कुछ एक NSFetchedResultController से लिया जाता है। क्या कोई उदाहरण परियोजनाएं या दस्तावेज़ीकरण है जो ऐसा करने का प्रदर्शन करता है?

धन्यवाद

उत्तर

24

एक पल के लिए मान लें अपने शीर्षक में निम्नलिखित (नीचे दिए गए कोड से थोड़ा लापरवाह, मेरी क्षमा याचना हो जाएगा):

NSFetchedResultsController *fetchedResultsController1; // first section data 
NSFetchedResultsController *fetchedResultsController2; // second section data 

तालिका पता है कि तुम 2 वर्गों के लिए चाहते हैं:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 2; // you wanted 2 sections 
} 

यह दे दो खंड शीर्षक:

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { 
    return [NSArray arrayWithObjects:@"First section title", @"Second section title", nil]; 
} 

तालिका जानते हैं कि कैसे कई पंक्तियों वर्गों प्रति देखते हैं करते हैं:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    if (section == 0) { 
     return [[fetchedResultsController1 fetchedObjects] count]; 
    } else if (section == 1) { 
     return [[fetchedResultsController2 fetchedObjects] count]; 
    } 

    return 0; 
} 

सेल बिल्ड:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    ... // table cell dequeue or creation, boilerplate stuff 

    // customize the cell 
    if (indexPath.section == 0) { 
     // get the managed object from fetchedResultsController1 
     // customize the cell based on the data 
    } else if (indexPath.section == 1) { 
     // get the managed object from fetchedResultsController2 
     // customize the cell based on the data 
    } 

    return cell; 
} 
+0

धन्यवाद गले लगाओ। वह भाग लगता है काफी सरल है, हालांकि ऐसे एक 2 अन्य तरीकों है कि मैं के बारे में इतना यकीन नहीं कर रहे हैं (वे क्या करते हैं और यदि वे किसी भी परिवर्तन की जरूरत है): http://pastebin.ca/1805761 – indragie

+0

यह एक तरह से क्या पर निर्भर करता है आपके ऐप करता है; ऐप, डिज़ाइन इत्यादि के बारे में पूरी तरह से जानने के बिना मुझे जवाब देना मुश्किल है। हालांकि, आपके पास शायद उन विधियों को एक रीलोडडेटा संदेश देखने के लिए एक सुरक्षित विकल्प है। – Giao

+0

यह थोड़ा tinkering के साथ काम करने के लिए प्रबंधित :-) धन्यवाद – indragie

3

दो NSFetchedResultsControllers साथ Giao के समाधान का विस्तार - हम अपने NSFetchedResultsController के बारे में पता नहीं है याद करने के लिए है हमारे दो खंड और वापस लौटे NSIndexPathes हमेशा पहले खंड के लिए होंगे।

तो जब हम सेल विन्यास में एक वस्तु हो रही है: जबकि NSFetchedResultsController कुछ परिवर्तन देखा

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; 
    if (!cell) { 
     [tableView registerNib:[UINib nibWithNibName:@"cell" bundle:nil] forCellReuseIdentifier:@"cell"]; 
     cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; 
    } 
    [self configureCell:cell atIndexPath:indexPath]; 
    return cell; 
} 

-(void)configureCell:(UITableViewCell*)cell atIndexPath:(NSIndexPath *)indexPath { 
    if (indexPath.section == 0) { 
     NSManagedObject *object = [self.fetchedResults1 objectAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:0]]; 
     //use object to configure cell 
    } else { 
     NSManagedObject *object = [self.fetchedResults2 objectAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:0]]; 
     //use object to configure cell 
    } 
} 

कोशिकाओं अपडेट कर रहा है:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { 
    NSIndexPath *customIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:(controller == self.fetchedResultsController1)?0:1]; 
    NSIndexPath *customNewIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:(controller == self.fetchedResultsController2)?0:1]; 
    switch(type) { 
     case NSFetchedResultsChangeInsert: 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:customNewIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
     case NSFetchedResultsChangeDelete: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:customIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
     case NSFetchedResultsChangeUpdate: 
      [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
      break; 
     case NSFetchedResultsChangeMove: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:customIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:customNewIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 
+0

अच्छा जवाब लेकिन ऐप 'performFetch' को फिर से लॉन्च करने के बाद अन्यथा संदर्भित किया जाना चाहिए संदर्भ में प्रबंधित प्रबंधित ऑब्जेक्ट्स खो देता है। कोई मदद? – Goppinath

1

एकाधिक नियंत्रकों (और संभवतः कई संस्थाओं) गलत दृष्टिकोण है लाने । परिणामों का समूह कई वर्गों में समूहित करने के लिए पैरामीटर NSFetchedResultController पर सही समाधान का उपयोग करना है। यदि आप अपनी संस्थाओं के बारे में अलग-अलग सोचते हैं तो शायद वे वास्तव में एक ही इकाई हैं और इसके बजाय आप एक प्रॉपर्टी आइटम टाइप का उपयोग कर सकते हैं जिस पर आप अनुभाग कर सकते हैं (और आपको इसे भी सॉर्ट करना होगा)। जैसे कहें कि मेरे पास हॉप और अनाज की इकाइयां थीं, तो मैं उन्हें घटक के रूप में बदल सकता हूं और एक int_16 प्रॉपर्टी घटक टाइप कर सकता हूं जिसमें मेरे पास hopType = 0, grainType = 1 मानों को संग्रहीत करने के लिए कोड में एक enum है। सभी घटक के बाद सिर्फ एक नाम और वजन है, जो इन दोनों शेयरों में से हैं।

यदि आपकी संस्थाओं के पास वास्तव में गुणों का एक अलग समूह है, तो सही समाधान एक मूल सारणी इकाई बनाना है जिसमें एक संपत्ति है जिसका आप अनुभाग में उपयोग कर सकते हैं, उदा। sortOrder, sectionID या प्रकार। जब आप एक fetch नियंत्रक बनाते हैं और अमूर्त पैरेंट इकाई प्राप्त करते हैं, तो आपको वास्तव में सभी उप-इकाइयों वाले परिणाम मिलते हैं। नोट्स ऐप में उनके पास एक सारणी इकाई नोटकॉन्टेनर है जिसमें उप-संस्थाएं खाता और फ़ोल्डर हैं।इस तरह वे अनुभाग में पहले सेल में खाता प्रदर्शित करने के लिए एक एकल fetch नियंत्रक का उपयोग कर सकते हैं, और उसके बाद निम्न कक्षों में सभी फ़ोल्डर्स हैं। जैसे सभी iCloud नोट्स (वास्तव में खाता है), फिर नोट्स (डिफ़ॉल्ट फ़ोल्डर है), उसके बाद सभी कस्टम फ़ोल्डर्स, फिर कचरा फ़ोल्डर। वे एक sortOrder प्रॉपर्टी का उपयोग करते हैं और डिफ़ॉल्ट फ़ोल्डर 1 होता है, कस्टम फ़ोल्डर्स सभी 2 होते हैं, और ट्रैश 3 होता है। फिर इसे एक प्रकार के डिस्क्रिप्टर के रूप में जोड़कर वे कोशिकाओं को क्रम में प्रदर्शित कर सकते हैं। यह आपकी आवश्यकता से थोड़ा अलग है क्योंकि उनके पास 2 इकाइयां अलग-अलग वर्गों में मिश्रित हैं, लेकिन आप अभी भी विभिन्न प्रकार के गुणों के साथ इसका उपयोग कर सकते हैं।

कहानी का नैतिक ढांचे लड़ाई नहीं करते है, यह विस्तृत जवाब के लिए :-)

संबंधित मुद्दे