2012-07-17 8 views
5

मैंने क्लिक करने योग्य अनुभागों के साथ एक UITableview बनाया है। आप उन पर क्लिक करते हैंinsertRowsAtIndexPaths: scrollToRowAtIndexPath के साथ: UITableView अनुभाग गलत तरीके से छुपाए जाने का कारण बनता है

  1. वे "विस्तार" दृश्य के शीर्ष करने के लिए क्लिक अनुभाग स्क्रॉल उन्हें
  2. के भीतर कोशिकाओं प्रकट करने के लिए।

मैं indexpaths के सभी डालने के लिए/आवश्यक कोशिकाओं को नष्ट और फिर उन्हें निम्न कोड के साथ सम्मिलित गणना:

[self.tableView beginUpdates]; 
[self.tableView insertRowsAtIndexPaths:pathsToOpen withRowAnimation:insertAnimation]; 
[self.tableView deleteRowsAtIndexPaths:pathsToClose withRowAnimation:deleteAnimation]; 
[self.tableView endUpdates]; 
[self.tableView scrollToRowAtIndexPath:[pathsToOpen objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

नहीं है केवल एक ही समस्या चयनित अनुभाग नीचे दिए गए अनुभागों छिपे हुए हैं। पहला स्क्रीन-शॉट दिखाता है कि टेबलव्यू कैसे दिखना चाहिए। दूसरा स्क्रीन-शॉट दिखाता है कि यह वास्तव में कैसा दिखता है।

Sections Disappear

आप ऊपर स्क्रॉल (ताकि छिपा वर्गों गुप्त कर रहे हैं) और फिर वापस नीचे स्क्रॉल, तो छिपा वर्गों वापस (एक बार फिर से दिखाई दे) लाया जाता है। मेरा अनुमान है कि यह क्यों हो रहा है निम्न है:

scrollToRowAtIndexPath के रूप में एक ही समय में सम्मिलित/हटाएं एनिमेशन हो रहा है और यह TableView को भ्रमित कर रहा है। अगर मैंने scrollToRowAtIndexPath अनुभाग नहीं किया था 3 & 4 ऑफ़स्क्रीन होगा - और इसलिए तालिका किसी भी तरह से सोचती है कि वे ऑफस्क्रीन हैं। UITableview सेल/अनुभाग छुपाता है जो ऑप्टिमाइज़ेशन के रूप में ऑफस्क्रीन हैं। यदि मैं को dispatch_after के साथ 2 सेकंड के साथ कॉल करता हूं, तो अनुभाग 3 & 4 सही तरीके से प्रदर्शित होते हैं।

तो मुझे लगता है कि मुझे पता है कि यह क्यों हो रहा है, लेकिन मुझे नहीं पता कि इस UITableview अनुकूलन को कैसे ठीक/ओवरराइड करना है। असल में, अगर मैं scrollViewDidEndScrollingAnimation लागू करता हूं और फिर इस फ़ंक्शन में ब्रेकपॉइंट जोड़ता हूं, तो ऐप अनुभाग 3 & 4 सही तरीके से प्रदर्शित करता है (इस तरह मुझे पहला स्क्रीन-शॉट मिला)। लेकिन एक बार इस समारोह से जारी रखने के बाद, कोशिकाएं गायब हो जाती हैं। धारा वैध UITableView अनुभाग हैं:

पूर्ण परियोजना here


अतिरिक्त कार्यान्वयन विवरण डाउनलोड किया जा सकता। मैंने एक टैपगेशर रिकॉग्नाइज़र जोड़ा है जो तालिका दृश्य में एक प्रतिनिधि कॉलबैक ट्रिगर करता है। नीचे दी गई पूरी विधि है जो अनुभाग खोलती है।

- (void)sectionHeaderView:(SectionHeaderView *)sectionHeaderView sectionOpened:(NSInteger)sectionOpened 
{ 
    // Open 
    sectionHeaderView.numRows = DefaultNumRows; 
    sectionHeaderView.selected = YES; 
    NSMutableArray *pathsToOpen = [[NSMutableArray alloc] init]; 
    for (int i = 0; i < sectionHeaderView.numRows; i++) 
    { 
     NSIndexPath *pathToOpen = [NSIndexPath indexPathForRow:i inSection:sectionOpened]; 
     [pathsToOpen addObject:pathToOpen]; 
    } 

    // Close 
    NSMutableArray *pathsToClose = [[NSMutableArray alloc] init]; 
    if (openSectionHeader) 
    { 
     for (int i = 0; i < openSectionHeader.numRows; i++) 
     { 
      NSIndexPath *pathToClose = [NSIndexPath indexPathForRow:i inSection:openSectionHeader.section]; 
      [pathsToClose addObject:pathToClose]; 
     } 
    } 

    // Set Correct Animation if section's already open 
    UITableViewRowAnimation insertAnimation = UITableViewRowAnimationBottom; 
    UITableViewRowAnimation deleteAnimation = UITableViewRowAnimationTop; 
    if (!openSectionHeader || sectionOpened < openSectionHeader.section) 
    { 
     insertAnimation = UITableViewRowAnimationTop; 
     deleteAnimation = UITableViewRowAnimationBottom; 
    } 

    openSectionHeader.numRows = 0; 
    openSectionHeader.selected = NO; 
    openSectionHeader = sectionHeaderView; 


    [self.tableView beginUpdates]; 
    [self.tableView insertRowsAtIndexPaths:pathsToOpen withRowAnimation:insertAnimation]; 
    [self.tableView deleteRowsAtIndexPaths:pathsToClose withRowAnimation:deleteAnimation]; 
    [self.tableView endUpdates]; 
    [self.tableView scrollToRowAtIndexPath:[pathsToOpen objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
} 
+0

मुझे लगता है कि आप ऐप्पल द्वारा प्रदान किए गए एमवीसी का बेहतर उपयोग कर सकते हैं। आपको बस अपने डेटासोर्स में डेटा जोड़ने/निकालना है और तालिकादृश्य पंक्तियों को छूना नहीं है – divol

+0

कृपया डाउनलोड में अपेक्षा करने के बजाय प्रश्न में अपनी परियोजना का थोड़ा और हिस्सा शामिल करें - उदाहरण के लिए, आप इंडेक्स पथ की गणना कैसे करते हैं जोड़ने/निकालने के लिए, और आपके "सेक्शन एक्स" चीजें सेक्शन हेडर हैं या वे सिर्फ सेल्स हैं? यह एक बेहतर स्टैंडअलोन सवाल के लिए तैयार होगा अगर यह आपकी परियोजना को डाउनलोड करने पर इतना निर्भर नहीं था। – jrturton

+0

मुझे लगता है कि आपका अनुमान सही है। क्या आप स्क्रॉल समाप्त प्रतिनिधि विधि पर पंक्तियों को फिर से लोड करने का प्रयास कर सकते हैं? – jrturton

उत्तर

6

जो मैं कह सकता हूं, समस्या तब हो रही है जब एक सेक्शन व्यू को वापस लौटाया जा रहा है। बजाय:

- (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section 
{ 
    return [self.sectionHeaderViews objectAtIndex:section]; 
} 

अगर मैं कोई नया दृश्य हर बार बनाने मुझे कोई समस्या नहीं मिलती है:

- (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section{ 
    SectionHeaderView *sectionHeaderView = [self.tableView dequeueReusableCellWithIdentifier:SectionHeaderView_NibName]; 
    sectionHeaderView.textLabel.text = [NSString stringWithFormat:@"Section %d", section]; 

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:sectionHeaderView action:@selector(handleTap:)]; 
    [sectionHeaderView addGestureRecognizer:tapRecognizer]; 
    sectionHeaderView.section = section; 
    sectionHeaderView.delegate = self; 
    return sectionHeaderView; 
} 

यह संभव इस उत्पन्न हो रही है क्योंकि आप अनुभाग शीर्ष लेख बना सकते हैं और उन पर पकड़ के लिए [self.tableView dequeueReusableCellWithIdentifier:SectionHeaderView_NibName]; उपयोग कर रहे हैं एक सरणी में, जो मुझे नहीं लगता कि UITableViewCell के लिए बनाया गया था, लेकिन मुझे यकीन नहीं है। आप अनुभाग दृश्यों के लिए पूर्वगामी UITableViewCell पर विचार करना चाहेंगे और इसके बजाय कुछ और उपयोग कर सकते हैं (शायद UILabel के साथ UIImageView)। या आप अनुभाग दृश्यों को किसी सरणी में संग्रहीत नहीं कर सकते ... जिस तरह से आपके पास वर्तमान में आपका कोड सेट है, आपको सरणी की आवश्यकता नहीं है और नया दृश्य बनाना पर्याप्त है, आपको इसके बारे में चिंता करने की आवश्यकता नहीं है।

4

@ AaronHayman का जवाब काम करता है (और IMO स्वीकार करते हैं और इनाम, उसे करने के लिए जाना चाहिए क्योंकि यह खड़ा है - यह सिर्फ एक टिप्पणी में फिट नहीं), लेकिन मुझे आगे जाना होगा - आप प्रयोग नहीं किया जाना चाहिए सेक्शन हेडर के लिए बिल्कुल एक सेल, और आपको अनिवार्य रूप से निब लोड करने के लिए डेक्यू तंत्र का उपयोग नहीं करना चाहिए।

अनुभाग हेडर व्यू को कोशिकाएं नहीं माना जाता है, और आप नियमित विचारों के स्थान पर उनका उपयोग करके असुरक्षित प्रभाव प्राप्त कर सकते हैं, खासकर अगर उन्हें हटा दिया जाता है - तालिका इन पुन: प्रयोज्य कोशिकाओं की सूची रखती है जब आप ऐसा करते हैं , और स्क्रीन पर जाने पर उन्हें रीसायकल करते हैं, लेकिन आपके सेक्शन हेडर पुन: प्रयोज्य नहीं हैं, आपके पास प्रति अनुभाग एक है।

अपने नमूना परियोजना में, मैं SectionHeaderView की सुपर क्लास बदल एक सादे UIView होने के लिए, और अपने createSectionHeaderViews पद्धति को बदल कर वहाँ महत्वपूर्ण व्यक्ति से सीधे लोड करने के लिए:

NSMutableArray *sectionHeaderViews = [[NSMutableArray alloc] init]; 
    UINib *headerNib = [UINib nibWithNibName:SectionHeaderView_NibName bundle:nil]; 
    for (int i = 0; i < 5; i++) 
    { 
     SectionHeaderView *sectionHeaderView = [[headerNib instantiateWithOwner:nil options:nil] objectAtIndex:0]; 
     sectionHeaderView.textLabel.text = [NSString stringWithFormat:@"Section %d", i]; 

     UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:sectionHeaderView action:@selector(handleTap:)]; 
     [sectionHeaderView addGestureRecognizer:tapRecognizer]; 
     sectionHeaderView.section = i; 
     sectionHeaderView.delegate = self; 

     [sectionHeaderViews addObject:sectionHeaderView]; 
    } 
    self.sectionHeaderViews = sectionHeaderViews; 

मैं भी पुन: उपयोग लाइन के लिए रजिस्टर पर टिप्पणी की आपके दृश्य से DidLoad। यह सेक्शन हेडर गायब होने से रोकता है।

+0

अच्छा विचार उसे दिखा रहा है कि कैसे एक निब से दृश्य को तुरंत चालू किया जाए। मैं आम तौर पर कोड में अपने सभी विचार बना देता हूं इसलिए मैंने इसके बारे में भी सोचा नहीं। –