UITableview: कुछ पंक्तियों के लिए चयन अक्षम कैसे करें, लेकिन अन्य नहीं


298

मैं tableviewXML से पार्स की गई समूह सामग्री में प्रदर्शित कर रहा हूं । मैं उस पर क्लिक इवेंट को अक्षम करना चाहता हूं (मुझे इसे क्लिक करने में सक्षम नहीं होना चाहिए) तालिका में दो समूह हैं। मैं केवल पहले समूह के लिए चयन को अक्षम करना चाहता हूं लेकिन दूसरे समूह को नहीं। दूसरे समूह की पहली पंक्ति navigatesको मेरी ट्यूब पर क्लिक करना player view

मैं केवल विशिष्ट समूहों या पंक्तियों को कैसे चुन सकता हूं?

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    if(indexPath.section!=0)
    if(indexPath.row==0)    

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:tubeUrl]];   
}

धन्यवाद।

जवाबों:


499

आपको बस इस कोड को डालना है cellForRowAtIndexPath

सेल की चयन संपत्ति को अक्षम करने के लिए: (सेल टैप करते समय)

cell.selectionStyle = UITableViewCellSelectionStyleNone;

सेल का चयन करने में सक्षम होने के लिए (टैप करें): (सेल को टैप करके)

// Default style
cell.selectionStyle = UITableViewCellSelectionStyleBlue;

// Gray style
cell.selectionStyle = UITableViewCellSelectionStyleGray;

ध्यान दें कि उपयोगकर्ता द्वारा छुआ जाने पर selectionStyle = UITableViewCellSelectionStyleNone;यूआई कॉल करने के लिए एक सेल अभी भी कारण होगा didSelectRowAtIndexPath। इससे बचने के लिए, जैसा कि नीचे दिया गया है और सेट करें।

cell.userInteractionEnabled = NO;

बजाय। यह भी ध्यान दें कि आप cell.textLabel.enabled = NO;आइटम को ग्रे करने के लिए सेट करना चाह सकते हैं ।


1
यदि आप हटाने के लिए स्वाइप करने का प्रयास करते हैं तो यह विधि बग उत्पन्न करेगी।
विवे

116
यह हैक है! ऐसा करें, नीचे दिए गए उत्तर का उपयोग करें - वापस आने वाले नील के साथ willSelectRowAtIndexPath का उपयोग करें!
पीटर स्टैजर

4
UserInteractionEnabled सामान सही नहीं है, हुक विल .SelectRowAtIndexPath को लोग नोट करते हैं।
जॉनी

23
IOS 6.0 और उसके बाद का, tableView:shouldHighlightRowAtIndexPath:एक नया UITableViewDelegateतरीका है BOOLजो पारित किए गए या नहीं पर आधारित indexPathहोना चाहिए। यदि आप 6.0 और बाद के लिए निर्माण कर रहे हैं, तो मैं दृढ़ता से इस नए एपीआई की सिफारिश करता हूं।
cbowns

3
यदि आप स्विफ्ट में ऐसा कर रहे हैं और आपको परेशानी हो रही है, लेकिन यहां समाप्त हो गई है, तो आपको यह निर्धारित करने की आवश्यकता होगी कि cell!.selectionStyle = .Noneकौन सा बल सेल को अलिखित करता है, जिससे आपको इसके गुणों का उपयोग करने की अनुमति मिलती है।
मार्कोस

371

यदि आप एक पंक्ति (या पंक्तियों का सबसेट) गैर-चयन करने योग्य बनाना चाहते हैं , तो UITableViewDelegateविधि को लागू करें -tableView:willSelectRowAtIndexPath:(TechZen द्वारा उल्लिखित भी)। यदि चयन करने योग्यindexPath नहीं होना चाहिए , तो वापस लौटें , अन्यथा वापस लौटें । डिफ़ॉल्ट चयन व्यवहार प्राप्त करने के लिए, आप बस अपने तरीके से पास लौटाते हैं , लेकिन आप पंक्ति चयन को अलग करके भी बदल सकते हैं ।nilindexPathindexPathdelegateindexPath

उदाहरण:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // rows in section 0 should not be selectable
    if ( indexPath.section == 0 ) return nil;

    // first 3 rows in any section should not be selectable
    if ( indexPath.row <= 2 ) return nil;

    // By default, allow row to be selected
    return indexPath;
}

2
छोटा विवरण: आप उल्लेख करते हैं <= 2, नहीं = <2. खराब स्माइली! :)
जोनास बिस्ट्राम

23
मैं यह भी जोड़ना चाहूंगा कि यह सही उत्तर है, लेकिन आपको चयन को भी सेट करना चाहिए UITableViewCellSelectionStyleNone में CellForRowAtIndexPath। क्यों? क्योंकि इस चयन शैली के बिना सेल का चयन नहीं किया जा सकता है, लेकिन इसे तब भी "चयनित" के रूप में प्रदर्शित किया जाएगा जब नीचे टच किया जाता है (इसलिए यह चयनित रंग में बदल जाता है, अगर अन्य कोशिकाओं के लिए एक है)
18

4
यह स्वीकृत उत्तर की तुलना में अधिक होना चाहिए
user1244109

2
मुझे लगता है कि मुख्य कारण यह स्वीकृत उत्तर नहीं है क्योंकि स्वीकृत उत्तर आसान है। हालांकि यह 'सबसे अच्छा तरीका' नहीं है, क्योंकि आपकी तालिका अभी भी सेटिलेटेड कहेगी: आपकी कोशिकाओं पर, यह अभी भी काम करता है, नेत्रहीन। यह उत्तर यहां अधिक काम करता है, लेकिन इसे करने का उचित तरीका है (आपको अपनी कोशिकाओं पर तालिका सेट किए गए: कॉल करने वाले तालिका के किसी भी अप्रत्याशित परिणामों से बचने के लिए @TooManyEduardos सुझाव के साथ ही मेल करना चाहिए)।
ब्रायन सचेटा

मैं इस सवाल का जवाब की तरह, लेकिन अगर आप cellForRowAtIndexPath और willSelectRowAtIndexPath में अपने तर्क नकल नहीं करना चाहते, बस अगर वापसी नहीं के बराबर करने के लिए willSelectRowAtIndexPath में cell.selectionStyle == कोई भी (नीचे मेरा उत्तर देखें) की जाँच
एरिक डिसूजा

61

IOS 6 में शुरू, आप उपयोग कर सकते हैं

-tableView:shouldHighlightRowAtIndexPath:

यदि आप वापस लौटते हैं NO, तो यह चयन हाइलाइटिंग और स्टोरीबोर्ड दोनों को निष्क्रिय कर देता है, जो उस सेल से जुड़े सेगमेंट को ट्रिगर करता है।

किसी पंक्ति पर स्पर्श आने पर विधि को कहा जाता है। NOउस संदेश पर वापस लौटने से चयन प्रक्रिया रुक जाती है और वर्तमान में चयनित पंक्ति के कारण उसका चयन नहीं हो पाता है, जबकि टच डाउन होता है।

UITableViewDelegate प्रोटोकॉल संदर्भ


3
माना। IOS 7 और इसके बाद के संस्करण के लिए पसंदीदा तरीका होना चाहिए (वास्तव में iOS 8 पर अन्य तरीके मेरे लिए काम नहीं कर रहे थे।)
race_carr

यह शीर्ष उत्तर होना चाहिए।
कैमरून ई

16

उपरोक्त उत्तरों में से कोई भी वास्तव में समस्या को सही तरीके से संबोधित नहीं करता है। कारण यह है कि हम सेल के चयन को अक्षम करना चाहते हैं, लेकिन आवश्यक नहीं कि सेल के अंदर ही साक्षात्कार हों।

मेरे मामले में मैं पंक्ति के बीच में एक UISwitch प्रस्तुत कर रहा था और मैं बाकी पंक्ति के लिए चयन को अक्षम करना चाहता था (जो खाली है) लेकिन स्विच के लिए नहीं! ऐसा करने का उचित तरीका विधि में है

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

जहां फार्म का एक बयान

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

विधि जो केवल कोशिका को तैयार करती है और यूआईस्विच के साथ बातचीत की अनुमति नहीं देती है।

इसके अलावा, विधि का उपयोग कर

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

फार्म के एक बयान के साथ सेल को रद्द करने के लिए

[tableView deselectRowAtIndexPath:indexPath animated:NO];

अभी भी पंक्ति को चुना जा रहा है, जबकि उपयोगकर्ता सेल के मूल contentView पर दबाता है।

केवल मेरे दो सेंट्स। मुझे पूरा यकीन है कि कई लोग इसे उपयोगी पाएंगे।


इस बात से सहमत। और willSelectRowAtIndexPathएक ही मुद्दे में नील को लौटाना , साक्षात्कार चयन नहीं हैं।
jeffjv

यह भी ध्यान दें कि यदि आपके पास एक स्टैटिक टेबल है तो आप सिलेक्शन को किसी भी इंटरफेस बिल्डर में उन कोशिकाओं के लिए सेट कर सकते हैं जहाँ आप चयन नहीं करना चाहते हैं।
jeffjv

11

आप इन डेटा स्रोत विधियों के साथ चयन को फँसाते हैं।

 tableView:willSelectRowAtIndexPath: 
 tableView:didSelectRowAtIndexPath: 
 tableView:willDeselectRowAtIndexPath: 
 tableView:didDeselectRowAtIndexPath:

इन विधियों में, आप जांचते हैं कि चयनित पंक्ति वह है जिसे आप चयन करना चाहते हैं। यदि ऐसा है, तो कार्रवाई करें, यदि नहीं, तो कुछ भी न करें।

दुर्भाग्य से, आप केवल एक सेक्शन के लिए चयन को बंद नहीं कर सकते। यह पूरी मेज है या कुछ भी नहीं है।

हालाँकि आप तालिका कक्षों को selectionStyleगुण पर सेट कर सकते हैंUITableViewCellSelectionStyleNone । मुझे विश्वास है कि चयन को अदृश्य बना देगा। उपरोक्त तरीकों के साथ संयुक्त है जो कोशिकाओं को उपयोगकर्ता के दृष्टिकोण से पूरी तरह निष्क्रिय होना चाहिए।

Edit01:

यदि आपके पास एक तालिका है जिसमें केवल कुछ पंक्तियाँ चयन करने योग्य हैं तो यह महत्वपूर्ण है कि चयन करने योग्य पंक्तियों की कोशिकाएँ गैर-चयन योग्य पंक्तियों से नेत्रहीन भिन्न हों। शेवरॉन एक्सेसरी बटन ऐसा करने का डिफ़ॉल्ट तरीका है।

हालाँकि आप ऐसा करते हैं, आप नहीं चाहते हैं कि आपके उपयोगकर्ता पंक्तियों का चयन करने की कोशिश करें और सोचें कि ऐप खराब हो गया है क्योंकि पंक्ति कुछ भी नहीं करती है।


कृपया इन विधियों का उपयोग करने या कुछ नमूना कार्यक्रम लिंक देने के बारे में विस्तार से बताएं
योद्धा

2
@Warrior: यदि आपने SDK स्थापित किया है तो आप Xcode खोल सकते हैं, पर जा सकते हैं Help -> Developer documentation, फिर खोज विधि में उन तरीकों के नामों को कॉपी करके देखें कि यह कैसे काम करता है। डेवलपर प्रलेखन में नमूना कोड भी होता है।
kennytm


9

cellForRowAtIndexPathविधि के भीतर सेल चयन को अक्षम करने के लिए आपको कुछ करने की आवश्यकता है :

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell setUserInteractionEnabled:NO];

सेल को धूसर दिखाने के लिए, निम्नलिखित को tableView:WillDisplayCell:forRowAtIndexPathविधि में रखें:

[cell setAlpha:0.5];

एक विधि आपको अन्तरक्रियाशीलता को नियंत्रित करने की अनुमति देती है, दूसरी आपको यूआई उपस्थिति को नियंत्रित करने की अनुमति देती है।


5

केवल कुछ कोशिकाओं के उपयोग को रोकने के लिए:

cell.userInteractionEnabled = NO;

चयन को रोकने के साथ-साथ, यह टेबलव्यू को भी रोकता है: didSelectRowAtIndexPath: यह उन कोशिकाओं के लिए कहा जा रहा है जिन्होंने इसे सेट किया है।


1
एक अजीब बात हर समय होती है: जब मैं userInteractionEnabledएक सेल पर NO (अधिक स्पष्ट रूप से, एक indexPath) पर सेट करता हूं , तो कुछ अन्य कोशिकाओं के उपयोगकर्ता इंटरैक्शन अक्षम होते हैं। मुझे इस बात का कोई मलाल नहीं है कि ऐसा हर बार तब होता है जब मैं userInteractionEnabledटेबल व्यू सेल पर उपयोग करता हूं । यह एक ज्ञात बग है या मैंने कुछ गलत किया है?
फिलिप ०० Phil

3
@ Philip007 क्या "NO" कोशिकाओं का पुन: उपयोग किया जा रहा है? यदि ऐसा है, तो आपको यह सुनिश्चित करने की आवश्यकता हो सकती है कि जब आप किसी सेल को समाप्त करते हैं, तो आप इसे "हाँ" पर सेट कर सकते हैं।
जोसेफ

1
इसे "YES" पर क्यों सेट करें? मैं चाहता हूं कि यह NO (उपयोगकर्ता इंटरैक्शन को अस्वीकार करें) .. एक विशिष्ट उदाहरण यह है कि मैंने पहली पंक्ति ( if [indexPath row] == 0) NOमें उपयोगकर्ता इंटरैक्शन सेट किया हैtableView:cellForRowAtIndexPath: सेल को समाप्त बाद किया है। यह आमतौर पर पहली बार में ठीक काम करता है। फिर के कई कॉल के बाद reloadData, अचानक पाँचवीं पंक्ति को बातचीत से रोक दिया जाता है, फिर चौथी पंक्ति .. मैं यह पता नहीं लगा सकता कि यह कब होगा। पूरी बात यादृच्छिक लगती है।
फिलिप ०० Phil

6
@ Philip007 आप कोशिकाओं पुन: उपयोग कर रहे हैं, तो आप कोशिकाओं आप के लिए "हाँ" करने के लिए इसे रीसेट करने की आवश्यकता होगी है इंटरैक्टिव होना चाहता हूँ। अन्यथा यदि एक "NO" सेल को एक पंक्ति में पुन: उपयोग किया जाता है जिसे आप संवादात्मक बनाना चाहते हैं, तो यह अभी भी अक्षम होगा। अर्थात:if [indexPath row] == 0) { set to NO } else { set to YES }
जोसेफ

5

आप tableView:willDisplayCelltableViewCell के सभी प्रकार के अनुकूलन करने के लिए विधि का उपयोग कर सकते हैं ।

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
     [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
     [cell setUserInteractionEnabled:NO];

     if (indexPath.section == 1 && indexPath.row == 0)
     {
         [cell setSelectionStyle:UITableViewCellSelectionStyleGray];
         [cell setUserInteractionEnabled:YES];
     }
} 

इस उपरोक्त कोड में, उपयोगकर्ता तालिका के दूसरे भाग में केवल पहली पंक्ति का चयन कर सकता है। बाकी सभी पंक्तियों का चयन नहीं किया जा सकता है। धन्यवाद! ~



5

डेटा मॉडल पर आधारित मेरा समाधान:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
    return rowDetails.enabled ? indexPath : nil
}

func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
    let rowDetails = viewModel.rowDetails(forIndexPath: indexPath)
    return rowDetails.enabled
}

5

स्विफ्ट 4.0 के लिए यह ट्रिक करेगा। यह didSelectRowAtIndexPath पद्धति में सेल को अक्षम कर देगा, लेकिन उप-क्लिकों को क्लिक करने योग्य बनाए रखेगा।

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
         if (indexPath.row == clickableIndex ) { 
            return indexPath
         }else{
            return nil
        }
    }

या संक्षेप में: return indexPath.row == clickableIndex ? indexPath : nilअपने कोड को थोड़ा साफ रखता है ;-)
मार्क

1

सेल बनाने के लिए इसका उपयोग करें देखो की तरह यह विकलांग और गैर चयन है:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

महत्वपूर्ण: ध्यान दें कि यह केवल एक स्टाइलिंग संपत्ति है, और वास्तव में सेल को अक्षम नहीं करता है। ऐसा करने के लिए, आपको selectionStyleअपने didSelectRowAtIndexPath:प्रतिनिधि कार्यान्वयन में जाँच करनी होगी :

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if(cell.selectionStyle == UITableViewCellSelectionStyleNone) {
        return;
    }

    // do your cell selection handling here
}

1

मुझे ऊपर ब्रायन चैपडोस का जवाब पसंद है। हालाँकि, इसका मतलब यह है कि आपके पास सेलफोररॉएट इंडेक्सएक्सपैथ और फिर विलसैलेट्रॉवऑटइंडैक्सपैथ दोनों में तर्क हो सकते हैं जो आसानी से सिंक से बाहर निकल सकते हैं। तर्क की नक़ल करने के बजाय, बस चयन की जाँच करें:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.selectionStyle == UITableViewCellSelectionStyleNone)
        return nil;

    else
        return indexPath;
}

1

मुझे यह आसान लगा क्योंकि यह स्थिर और गतिशील दोनों तालिकाओं के साथ काम करता है। मैं केवल उन कोशिकाओं पर प्रकटीकरण संकेतक सेट करता हूं जिन्हें मैं चयन करने की अनुमति देना चाहता हूं।

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.accessoryType != UITableViewCellAccessoryDisclosureIndicator) {
        return nil;
    }
    return indexPath;
}

1

कोडिंग के बिना Xcode 7 पर आप बस निम्नलिखित कार्य कर सकते हैं:

बाह्यरेखा दृश्य में, तालिका दृश्य कक्ष का चयन करें। (सेल को टेबल व्यू कंट्रोलर सीन> टेबल व्यू कंट्रोलर> टेबल व्यू के तहत नेस्ट किया गया है। टेबल व्यू सेल देखने के लिए आपको उन वस्तुओं का खुलासा करना पड़ सकता है)

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


0

सरल

cell.userInteractionEnabled = YES;अगर यह नेविगेट कर सकता है और cell.userInteractionEnabled = NO;अन्यथा सेल के लिए बस का उपयोग करें


1
यह सेल के भीतर किसी भी सहायक दृश्य के साथ बातचीत को भी रोकता है, जो कि वांछित व्यवहार नहीं हो सकता है।
ग्रेग ब्राउन

0

tableView:willSelectRowAtIndexPath: अपनी तालिका के लिए डेटा स्रोत में केवल विधि लागू करें। यदि आप हाइलाइट करने के लिए पथ पर पंक्ति चाहते हैं, तो दिए गए indexPath को वापस करें। यदि आप नहीं करते हैं, तो शून्य लौटें।

मेरे ऐप से उदाहरण:

- (NSIndexPath *)tableView:(UITableView *)tableView
    willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MySelectableObj* obj = [self objectAtPath:indexPath];
    if(obj==nil) return nil;
    return indexPath;
}

इसके बारे में अच्छी बात यह है कि shouldPerformSegueWithIdentifier:sender:उपरोक्त विधि शून्य होने पर इसे कॉल नहीं किया जाएगा, हालांकि मैं पूरी तरह से पूर्णता के लिए उपरोक्त परीक्षण दोहराता हूं।



0

मैं ब्रायन के जवाब से सहमत हूं

यदि मैं करता हूँ

cell.isUserInteractionEnabled = false 

तब सेल के भीतर होने वाले साक्षात्कार उपयोगकर्ता से इंटरैक्ट नहीं होंगे।

दूसरी साइट पर, सेटिंग

cell.selectionStyle = .none

चयन रंग को अद्यतन नहीं करने के बावजूद डिडक्ट पद्धति को ट्रिगर करेगा।

UseSelectRowAt जिस तरह से मैंने अपनी समस्या को हल किया है। उदाहरण:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {

    if indexPath.section == 0{

        if indexPath.row == 0{
            return nil
        }

    }
    else if indexPath.section == 1{

        if indexPath.row == 0{
            return nil
        }

    }

    return indexPath

}

0

से Appart tableView.allowsMultipleSelection = trueआप अनुभाग का चयन करते की कोशिकाओं के बाकी का चयन रद्द करने की आवश्यकता होगी:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if indexPath.section does not support multiple selection {
        // deselect the rest of cells
        tableView
            .indexPathsForSelectedRows?.compactMap { $0 }
            .filter { $0.section == indexPath.section && $0.row != indexPath.row }
            .forEach { tableView.deselectRow(at: $0, animated: true) }
    }
}

-1

स्विफ्ट 3.0 के लिए आप यूआईटेबल व्यू सेल में उपयोगकर्ता इंटरैक्शन को अक्षम करने के लिए नीचे दिए गए कोड का उपयोग कर सकते हैं

 cell.isUserInteractionEnabled = false
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.