2011-11-24 15 views
23

में डिज़ाइन किए गए UITableView से एक स्टेटिक सेल को कैसे निकालें समाधान शायद बहुत आसान है, लेकिन मुझे यह नहीं मिल सका ..!स्टोरीबोर्ड

स्टोरीबोर्ड (आईओएस 5) के साथ काम करना, मेरे पास tableViewController है, और प्रत्येक अनुभाग के अंदर differents स्थिर सेल के साथ 5 अनुभागों के साथ एक डिज़ाइन किया गया स्टेटिक टेबलव्यू है।

मेरा प्रश्न है: viewWillAppear में प्रोग्राम को सेलैटिक रूप से कैसे हटाएं?

उदाहरण के लिए, मैं एक सेल एक तारीख

IBOutlet UITableViewCell * cellForDate; 

और .. के लिए बनाया गया वहाँ की तारीख नहीं है अगर है, मैं अपने सेल निकालना चाहते हैं।

cellForDate.hidden = true; //Hide the cell, but leave a blank space 

Ive की कोशिश की [tableView deleteRowsAtIndexPaths...] काम नहीं किया

किसी को भी एक विचार है? अपनी टिप्पणी के लिए

[tableView beginUpdates]; 
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:r inSection:s]]]; 
[tableView endUpdates]; 

जवाब में:

उत्तर

30

कोशिश से पहले ही दिखाया गया है, UITableViewDelegate की tableView:willDisplayCell:forRowAtIndexPath: विधि में। यह अंतिम विधि है जहां आप सेल की उपस्थिति में हेरफेर कर सकते हैं। हालांकि यह सेल को ले जाने वाली जगह को नहीं हटाएगा, इसलिए एक और चीज जिसे आप कोशिश कर सकते हैं, उसी प्रोटोकॉल के tableView:heightForRowAtIndexPath: विधि का उपयोग करके सेल पंक्ति की ऊंचाई 0 पर सेट करना है।

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

+1

दरअसल, यह तरीका एकमात्र तरीका है जिसे मैंने समस्या को हल करने के लिए पाया है, विधि ऊंचाई ForRowAtIndexPath, इंडेक्सपैथ के लिए एक स्विच है और इस फ़ंक्शन के अंदर सत्यापन कर रहा है। यदि यह शून्य है, तो मैं आईबीओलेट यूआईटीबल व्यूसेल संदर्भ के साथ सेल छुपा रहा हूं, और 0 लौटा रहा हूं .. सेल चला गया है! 20 से अधिक कोशिकाओं के होने पर यह थोड़ा डरावना हो रहा है, लेकिन यह अच्छा काम करता है! – Marc

+1

यह सभी समस्याओं को हल करता है https://github.com/xelvenone/StaticDataTableViewController/ –

0

आप हटाना कॉल और endUpdates के बाद से पहले beginUpdates लगाने की जरूरत है सेल को छिपाने के लिए

- (NSInteger)tableView:(UITableView)tableView numberOfRowsInSection:(NSInteger)section { 
    NSInteger ret; 
    switch (section) { 
     case 0: 
      // sectionZeroRows doesnt have to be a 
      // property (an attribute works just fine), but it 
      // helps with explaining this example. 
      ret = self.sectionZeroRows; 
      break; 
     // ... 
    } 
    return ret; 
} 

- (void)someMethod { 
    --self.sectionZeroRows; 
    [tableView beginUpdates]; 
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]]]; 
    [tableView endUpdates]; 
} 
+0

यह मेरे कि दुर्घटना त्रुटि दे: ** * अपरिपक्व अपवाद के कारण ऐप को समाप्त करना 'एनएसआईएननल इन्कॉन्सिस्टेंसी अपवाद', कारण: 'अमान्य अद्यतन: खंड 4 में पंक्तियों की अवैध संख्या। अद्यतन के बाद मौजूदा खंड में निहित पंक्तियों की संख्या (3) में पंक्तियों की संख्या के बराबर होना चाहिए वह खंड अद्यतन (3) से पहले, उस खंड से डाले गए या हटाए गए पंक्तियों की संख्या (0 डाला गया, 1 हटाया गया) और प्लस या घटाएं पंक्तियों की संख्या उस अनुभाग में या बाहर ले जाया गया है (0 स्थानांतरित हो गया है, 0 स्थानांतरित हो गया है)। ' – Marc

+0

ओह हाँ, आपको उस अनुभाग के लिए कक्षों की संख्या सेट करने की आवश्यकता है .. अपनी 'तालिका दृश्य में: संख्याऑफरोइनसेक्शन:' विधि, जो भी चर पंक्तियों की संख्या धारण कर रहा है, इसे 1 से कम करें, इसलिए यह विधि 5 के बजाय 4 की बदलेगी खंड (या हालांकि कई आवश्यक है)। – chown

+0

ठीक है, मैं समझता हूं, मैं आईओएस 5 में टेबलव्यू कंट्रोलर का उपयोग करके स्टोरीबोर्ड और टेबलव्यू के साथ काम करने का एक नया तरीका तलाश रहा था और मैं प्रतिनिधि और डेटासोर्स विधियों को ओवरराइट नहीं कर रहा था .. क्योंकि मेरा डेटासॉर मेरी स्टोरीबोर्ड में मेरी स्थिर तालिका थी ../////// आप नंबरऑफ्रोइन्स विधि का उपयोग कैसे करेंगे, यह जानने के लिए कि क्या मैंने अभी एक पंक्ति हटा दी है क्योंकि मैं viewDidAppear विधि से पंक्ति को हटा रहा हूं। क्या मुझे बस प्रत्येक वर्ग के लिए एक var रखना चाहिए, और बस मेरे var अद्यतन किया? – Marc

-1
// just authed with facebook, and I want to delete the first 3 rows of my 4 row table that are no longer necessary  
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { 
    if(wantsFacebook) 
     return 1; 

    return 4; 
} 

अपडेट करने के बाद, tableView पंक्तियों की अद्यतन संख्या प्राप्त करने numberOfRowsInSection प्रतिनिधि कॉल करेंगे और यह सही राशि/पंक्तियों के बीच अंतर किया जाना चाहिए जब आप डालने शुरू कर दिया/हटा सकते हैं और जब आप पंक्तियों सम्मिलित/हटाएं

3

यदि आप तालिकादृश्य कक्ष को स्थायी रूप से हटाना चाहते हैं, तो बस अपनी पंक्ति के अनुरूप इंडेक्सपैथ के साथ deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone] पर कॉल करें। आपको numberOfRowsInSection: द्वारा लौटाई गई पंक्तियों की संख्या में भी कमी करने की आवश्यकता होगी।

हालांकि, मैं अस्थायी रूप से एक स्थिर तालिकादृश्य से अवांछित स्थिर तालिकादृश्य कक्षों को "हटाएं" करने का एक तरीका ढूंढ रहा था, क्योंकि मैं कभी-कभी एक विशेष पंक्ति चाहता था, और अन्य बार नहीं। मैं भी tableview नियंत्रक के बाहर से मांग पर इसे अद्यतन करने में सक्षम होना चाहता था।

मेरा मामला काफी सरल है, क्योंकि यह पहली पंक्ति है जिसे दिखाया या छुपाया जा रहा था। आप अपनी जरूरतों के अनुसार सामान्यीकृत कर सकते हैं। मेरा टेबलव्यू नियंत्रक मेरा डेटा स्रोत प्रतिनिधि है।

पहले, मैं राज्य चर का अद्यतन करें और पुन: प्रदर्शित गति प्रदान करने के tableview नियंत्रक में एक सार्वजनिक विधि बनाया:

- (void)updateSettingsDisplay:(BOOL)hideSetting 
{ 
    if (hideSetting == self.hideSetting) { 
     return; // no need to do anything because it didn't change 
    } 

    self.hideSetting = hideSetting; 
    self.numRows = (hideSetting)? kNumRowsWithSetting : kNumRowsWithoutSetting; 

    // redisplay only if we're visible 
    if (!self.viewJustLoaded && (self.navController.visibleViewController == self)) { 
     [self.tableView reloadData]; 
    } 
    self.viewJustLoaded = NO; 
} 

tableview नियंत्रक के viewDidLoad लगता है:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // check whether or not to display out-of-coverage tableview cell 
    self.hideSetting = YES; // initial value; could just as easily be NO 
    self.viewJustLoaded = YES; 
    [self updateSettingsDisplay]; 
} 

tableview के डेटा- स्रोत प्रतिनिधि:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    // Return the number of rows in the section. 
    return self.numRows; 
} 

और अंतिम इसलिए का उपयोग करें कि आपके स्थिर tableview कोशिकाओं की स्थायी भंडारण के लिए - ly

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // set row to the index of the stored tableView cell that corresponds to the 
    // cell you want (its location in the static tableview from your storyboard) 
    NSInteger row = indexPath.row; 
    if (self.hideSetting) { 
     // skip drawing setting's tableviewcell (since the setting we're hiding is 
     // first, we can just increment the row to get the one we want) 
     ++row; 
     assert(row < kTotalRows); // bounds checking just to convince yourself (remove after testing) 
    } 
    // get a new index path since the row field is read-only 
    NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:row inSection:indexPath.section]; 

    // grab the cell from super that corresponds to the cell you want 
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:newIndexPath]; // static table 

    return cell; 
} 

चाल है कि स्थिर कोशिकाओं हमेशा [super tableView:tableView cellForRowAtIndexPath:newIndexPath] में उपलब्ध हैं। फिर आवश्यकतानुसार पंक्तियों की संख्या समायोजित करें, और पंक्तियों को सही ढंग से मानचित्र करें (यानी, अपने सेलव्यू प्रतिनिधि के cellForRowAtIndexPath: में पंक्तियों को संग्रहीत सेल की पंक्ति प्राप्त करें)।

updateSettingsDisplay विधि को आपके टेबलव्यू नियंत्रक पर किसी भी वर्ग द्वारा कॉल किया जा सकता है जो इसे बरकरार रखता है। यदि टेबलव्यू नियंत्रक दिखाई देने पर दिखाई नहीं देता है, तो यह केवल राज्य को अपडेट करेगा और अगली बार प्रदर्शित होने के लिए दृश्यमान होने तक प्रतीक्षा करेगा।

+0

आपके उत्तर का दूसरा भाग अच्छा दिखता है, लेकिन 'DeleteRowsAtIndexPaths' के साथ पहले पैराग्राफ का कोई प्रभाव नहीं है –

0

आप इस

https://github.com/xelvenone/StaticDataTableViewController/

उपयोग को देखने के लिए चाहते हो सकता है

self.hideSectionsWithHiddenRows = YES; //YES, NO 
[self cell:self.outletToMyStaticCell1 setHidden:hide]; 
[self cell:self.outletToMyStaticCell2 setHidden:hide]; 
[self reloadDataAnimated:YES]; 
24

उम्मीद है कि इस एक सार्वभौमिक समाधान के थोड़ा अधिक है, लेकिन यह अभी भी सही नहीं है

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; 
    if (cell.hidden) { 
     return 0; 
    } else { 
     return [super tableView:tableView heightForRowAtIndexPath:indexPath]; 
    } 
} 

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

इसके साथ एकमात्र मुद्दा यह है कि सूची और समूह के शीर्ष और निचले हिस्से में विभाजक के लिए प्रारंभ और अंत कोशिकाएं जिम्मेदार होती हैं। तो यदि आप किसी समूह में अंतिम सेल को छुपाते हैं तो समूह पर नीचे विभाजक थोड़ा सा इंसेट होगा जैसे कि यह पूर्ण चौड़ाई की बजाय सामान्य पंक्तियों पर है। यह केवल एक समस्या है यदि आप शीर्ष या निचली पंक्तियों को छुपा रहे हैं और आप एक विभक्त का उपयोग कर रहे हैं और आप पूरी तरह से मानक प्रदर्शन की परवाह करते हैं। मेरे मामले में सबसे अच्छा समाधान बस शीर्ष या निचली पंक्तियों को छिपाने के लिए नहीं था। मैंने किसी भी सामग्री को स्थानांतरित किया जो समूह के बीच में छुपाया जा सकता है। वैकल्पिक रूप से आप केवल यह स्वीकार कर सकते हैं कि यह काफी मानक नहीं है, या आपकी तालिका पर पंक्ति डिवाइडर अक्षम करें।

+0

जैसा कि आपने कहा है कि यह सही नहीं है, क्योंकि यह एक बनाता है रिकर्सिव ओवरफ्लो, हालांकि यदि आप उन पंक्तियों को जानते हैं जिन्हें आप छिपाना चाहते हैं और उनकी स्थिति आप केवल 'cellForRowAtIndexPath' कॉल को छोड़ सकते हैं और यह पूरी तरह से काम करता है। –

+0

@ होला सोया एडु फेलिज नेविदाद मुझे कोई रिकर्सन नहीं मिला। परीक्षण आईओएस 9. –

+0

यह केवल एक रिकर्सन बनाएगा यदि आपका सेलफॉररोएट इंडेक्सपैथ किसी भी तरह से ऊंचाई को कॉल करता है ForRowAtIndexPath। यह अनुचित नहीं है, लेकिन यह मानक व्यवहार भी नहीं है। यदि आप लेआउट के लिए सर्वोत्तम प्रथाओं का पालन कर रहे हैं तो आपको दो स्थानों में ऊंचाई की आवश्यकता नहीं होनी चाहिए। – ima747

1
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 

    if(indexPath.section == 1) { //For example 
     return 0 
    } 
} 

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    if(indexPath.section == 1) { 
     cell.hidden = true 
    } 
} 
0

FYI करें (टिप्पणी होगा अगर मैं कर सकता), यदि आप स्टोरीबोर्ड से एक समूहीकृत स्थिर UITableView अधिभावी कर रहे हैं, तो आप भी हैडर & पाद दृश्यों में से प्रत्येक अनुभाग में आप संशोधित कर रहे हैं के लिए & ऊंचाइयों को ओवरराइड करने की आवश्यकता होगी/छुपा रहे है।

मुझे शून्य के अलावा किसी अन्य चीज़ के लिए "गेटहेइट" विधियों के लिए वापसी मान सेट करने की भी आवश्यकता है - जिसका मतलब है कि शून्य मान का अर्थ कुछ और है (ऑटोलायआउट, या "सेट नहीं है" या जैसा)।

नीचे कोड में Xamarin आईओएस सी # है, लेकिन उचित Obj सी तरीकों के लिए सीधे अनुवाद:

public override void WillDisplayHeaderView(UITableView tableView, UIView headerView, nint section) 
    { 
     if (section == 0) 
     { 
      headerView = new UIView(new CGRect(0,0,0,0)); 
     } 
    } 

    public override nfloat GetHeightForHeader(UITableView tableView, nint section) 
    { 
     if (section == 0) 
     { 
      return 1f; 
     } 
     return base.GetHeightForHeader(tableView, section); 
    } 

    public override void WillDisplayFooterView(UITableView tableView, UIView footerView, nint section) 
    { 
     if (section == 0) 
     { 
      footerView = new UIView(new CGRect(0, 0, 0, 0)); 
     } 
    } 

    public override nfloat GetHeightForFooter(UITableView tableView, nint section) 
    { 
     if (section == 0) 
     { 
      return 1f; 
     } 
     return base.GetHeightForFooter(tableView, section); 
    } 
1

स्विफ्ट 3

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 
    if indexPath.section == 0 { 
     cell.isHidden = true 
    } 
} 

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
    if indexPath.section == 0 { 
     return 0 
    } else { 
     return super.tableView(tableView, heightForRowAt: indexPath) 
    } 
}