UITableViewCell क्यों हाइलाइट रहता है?


145

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

जवाबों:


262

अपने didSelectRowAtIndexPathआप deselectRowAtIndexPathमें सेल को अचयनित करने के लिए कॉल करने की आवश्यकता है ।

तो जो कुछ भी आप में कर रहे हैं, didSelectRowAtIndexPathबस उसे कॉल करें deselectRowAtIndexPath

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 // Do some stuff when the row is selected
 [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

11
मैं deselectRowAtIndexPathअपने दृश्य में कॉल करना पसंद करता हूं। यदि कोई नया दृश्य आता है तो पंक्ति का चयन करें।
notnoop

5
वास्तव में यह वास्तव में कॉल करने के लिए सही जगह नहीं है ... तालिकाओं के साथ एक ऐप्पल ऐप का उपयोग करने का प्रयास करें (संपर्क एक अच्छा है) और आप एक नई स्क्रीन पर धक्का देने के बाद देखेंगे, सेल पर अभी भी हाइलाइट किया गया है संक्षिप्त करने से पहले। सिद्धांत रूप में, मुझे लगता है कि आपको कोई अतिरिक्त काम करने की ज़रूरत नहीं है, इसे तुरंत अपने आप से हटा देना है, इसलिए viewDidAppear में कोड की आवश्यकता नहीं होनी चाहिए ...
Kendall Helmstetter Gelner

6
@ केंडल, @ 4thSpace: हो सकता है कि मेरी आखिरी टिप्पणी भ्रामक थी कि मैं किसकी बात कर रहा था, इसके लिए माफी। UITableViewController -deselectRowAtIndexPath:animated:अपनी tableView संपत्ति से विधि को कॉल करता है -viewDidAppear। हालाँकि, यदि आपके पास UIViewController उपवर्ग में एक तालिका दृश्य है, तो आपको स्वयं -deselectRowAtIndexPath:animated:से कॉल करना चाहिए -viewDidAppear। :)
डैनियल टुल्ल

5
UITableViewController के मेरे उपवर्ग में वास्तव में यह ओवरराइड था -viewWillAppear:कि इसे तोड़ दिया। [super viewWillAppear:animated]इसे फिर से काम करने के लिए एक कॉल जोड़ना ।
बेन चैलेंजर

5
3.2 के बाद से, स्वत: अचयन व्यवहार करता है, तो अपने होती है UITableViewControllerकी clearsSelectionOnViewWillAppearसंपत्ति के लिए सेट है YES(जो डिफ़ॉल्ट है), और आप को रोका नहीं किया है [super viewWillAppear]बुलाया जा रहा से।
डिफ्रैग्ड

62

यह करने के लिए सबसे साफ तरीका viewWillAppear पर है:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // Unselect the selected row if any
    NSIndexPath*    selection = [self.tableView indexPathForSelectedRow];
    if (selection) {
        [self.tableView deselectRowAtIndexPath:selection animated:YES];
    }
}

इस तरह आपके पास कंट्रोलर पर लौटने पर चयन को मिटाने का एनीमेशन है, जैसा कि यह होना चाहिए।

Http://forums.macrumors.com/showthread.php?t=577677 से लिया गया

स्विफ्ट संस्करण

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // deselect the selected row if any
    let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
    if let selectedRowNotNill = selectedRow {
        tableView.deselectRow(at: selectedRowNotNill, animated: true)
    }
}

1
यह वह है जो मुझे लगता है कि ज्यादातर लोग चाहते हैं कि वे UITableViewController का उपयोग न करें। +1
माइकबी

3
मुझे आश्चर्य है कि लोग अब क्या कर रहे हैं कि आईओएस 7 उपयोगकर्ता को वापस खींचने के लिए अनुमति देता है। आंशिक रूप से खींच रहा है, लेकिन फिर कार्रवाई पूरी नहीं होने पर दृश्य दिखाई देगा। जब उपयोगकर्ता वास्तविक के लिए लौटता है, तो पंक्ति का चयन नहीं किया जाएगा।
बेन पैकर्ड

1
@BenPackard viewDidAppearइसके बजाय केवल इसे कॉल करें ।
चौकोरफ्रॉग

@ जेसिका indexPathForSelectedRowकॉल शून्य वापस आ सकती है इसलिए इसकी जांच होनी चाहिए। प्रलेखन में कहा गया है : यदि अनुक्रमणिका पथ अमान्य है, तो चयनित पंक्ति की पंक्ति और अनुभाग अनुक्रमणिका की पहचान करने वाला एक सूचकांक पथ।
गॉर्डनियम

यह स्वीकार किए गए उत्तर के रूप में टिप्पणी करनी चाहिए, यह अधिक यूआई के अनुकूल है इसलिए उपयोगकर्ता वापस मिलने के बाद चयन तक पहुंच सकता है, परिपूर्ण
ar

20

क्या आपने उपवर्ग किया -(void)viewWillAppear:(BOOL)animated? जब आप [super viewWillAppear:animated];अपने कस्टम विधि में कॉल नहीं करते हैं तो चयनित UITableViewCell रद्द नहीं करेगा ।


19

स्विफ्ट उपयोगकर्ताओं के लिए, इसे अपने कोड में जोड़ें:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}

यह ओब्ज-सी के बजाय स्विफ्ट को छोड़कर पॉलथेनरड का जवाब है।


1
क्या यह अपने आप से रद्द नहीं हो जाता है, मेरा मतलब है कि जिस क्षण आप जाने दें?
शहद

@ यह संभवतः iOS के पिछले संस्करण में, या दृश्य के गायब होने पर संभव है, लेकिन निश्चित रूप से अब iOS 10 (पहले भी) और इसके बाद के संस्करण में नहीं।
जेमी बिर्च

9

स्विफ्ट 3 समाधान

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}

7

यदि आप UITableViewCell का उपयोग कर रहे हैं, तो निम्न लाइन पर टिप्पणी करें

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{

 // [super setSelected:selected animated:animated];

}

उम्मीद है की यह मदद करेगा।


4

स्विफ्ट 4 के साथ अपडेट किया गया

कुछ प्रयोगों के बाद, पिछले उत्तरों के आधार पर, मुझे यह निष्कर्ष मिला है कि सबसे अच्छा व्यवहार 2 तरीकों से प्राप्त किया जा सकता है: (व्यवहार में लगभग समान)

// First Solution: delegate of the table View
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: false)
}

// Second Solution: With the life cycle of the view.
override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)

    let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
    if let selectedRow = selectedRow {
        tableView.deselectRow(at: selectedRow, animated: false)
    }
}

मैं व्यक्तिगत रूप से पहला समाधान अपना रहा हूं, क्योंकि यह केवल अधिक संक्षिप्त है। एक और संभावना है, अगर आपको अपने टेबल व्यू पर लौटते समय थोड़ा एनीमेशन की आवश्यकता होती है, तो इसका उपयोग करना है viewWillAppear:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let selectedRow: IndexPath? = _view.tableView.indexPathForSelectedRow
    if let selectedRow = selectedRow {
        _view.tableView.deselectRow(at: selectedRow, animated: true)
    }
}

अंतिम लेकिन कम से कम, यदि आप UITableViewController का उपयोग कर रहे हैं, तो आप संपत्ति का लाभ भी ले सकते हैं ।SelectionOnViewWillAppear


3

व्यवहार प्राप्त करने के लिए केंडल हेल्मिस्सेटर गेलनर ने अपनी टिप्पणी में वर्णन किया है, आप संभवतः अपने नियंत्रक पर deselectRowAtIndexPath नहीं, बल्कि ClearSelectionOnViewWillAppear संपत्ति चाहते हैं। शायद यह दुर्घटना से हाँ में सेट था?

नए UITableViewController उपवर्गों के लिए डिफ़ॉल्ट Apple टेम्पलेट में टिप्पणी देखें:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;
}

2

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

मेरे मामले में समस्या यह है कि VC एक UIViewController था (जिसमें एक दृश्य था जिसमें एक TableView शामिल था)। इसके बजाय मैंने VC को UITableViewController बनाया (जिसमें एक TableView शामिल था)। UITableViewController क्लास एक पुश से लौटने के बाद स्वचालित रूप से टेबल सेल के डी-हाइलाइटिंग को संभालती है। पोस्ट का दूसरा उत्तर " टेबल व्यू में deselectRowAtIndexPath के साथ समस्या " इस समस्या का अधिक संपूर्ण उत्तर देता है।

रूट व्यूकंट्रोलर के लिए समस्या उत्पन्न नहीं हुई क्योंकि जब मैंने XCode में "नेविगेशन-आधारित ऐप" के रूप में ऐप बनाया, तो परिणामी रूट व्यूकंट्रोलर पहले से ही UITableViewController को उप-वर्ग के लिए बनाया गया था।


1

यदि आपके लिए इनमें से कोई भी काम नहीं है, तो इस काम पर विचार करें:

फोन करने के लिए एक आराम से बहस का उपयोग करें:

@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
    if let index = tableView.indexPathForSelectedRow {
        tableView.deselectRowAtIndexPath(index, animated: true)
    }
}

यह क्यों? मुख्य रूप से अगर आपको सही समय पर चलने के लिए अचयन कोड प्राप्त करने में समस्या हो रही है। मैं इसे देखने के साथ काम नहीं कर रहा था, जबकि विलेपियर ने काम किया था ताकि बहुत बेहतर काम हो सके।

कदम:

  1. अपने 1 वीसी (टेबल के साथ एक) में आराम से (या ऊपर से पेस्ट) लिखें

  2. 2 वीसी के पास जाओ। रद्द करें / पूर्ण / Etc बटन से नियंत्रण-ड्रैग करें जो आप उस VC को खारिज करने के लिए उपयोग कर रहे हैं और शीर्ष पर स्थित निकास आइकन पर खींचें।

  3. चरण 1 में आपके द्वारा बनाए गए लीग को चुनें

    सौभाग्य।


यह उस समय के लिए सबसे अच्छा समाधान है जब viewDidAppear फायर नहीं करता है (अर्थात यदि बच्चा दृश्य को औपचारिक रूप से एक फॉर्म शीट के रूप में प्रस्तुत किया जाता है और पूरी स्क्रीन को कवर नहीं करता है)।
फेदास्ता

1

मैं CoreData का उपयोग कर रहा हूं इसलिए मेरे लिए काम करने वाला कोड स्विफ्ट में विभिन्न उत्तरों से विचारों का संयोजन था:

override func viewDidAppear(_ animated: Bool) {
    if let testSelected = yourTable.indexPathForSelectedRow {
        yourTable.deselectRow(at: testSelected, animated: true)
    }
    super.viewDidAppear(true)
}

1
 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}

0

मैं लंबे समय से एक ही मुद्दे पर चल रहा हूँ ताकि कोई और संघर्ष करे:

अपने पर एक नज़र डालें -tableView: cellForRowAtIndexPath:और देखें कि क्या आप कोशिकाओं का निर्माण कर रहे हैं या 'पुन: उपयोग पहचानकर्ता' का उपयोग कर रहे हैं। यदि बाद वाला, सुनिश्चित करें कि IB में आपकी तालिका में उस पहचानकर्ता के साथ एक सेल है। यदि आप पुनः उपयोग पहचानकर्ता का उपयोग नहीं कर रहे हैं तो बस प्रत्येक पंक्ति के लिए एक नया सेल बनाएं।

इसके बाद आपको अपनी तालिका को प्रदर्शित होने पर अपेक्षित 'फीकी चयनित पंक्ति' देनी चाहिए।


0

इस विधि का उपयोग UITableViewCell क्लास में करें

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {

   // Just comment This line of code
   // [super setSelected:selected animated:animated];        
}

0

स्विफ्ट 3 के लिए: मैं इसे देखने में उपयोग करना पसंद करूंगा

परिभाषित करें: -

    var selectedIndexPath = IndexPath()

व्यूडीडिसैपियर में: -

    override func viewDidDisappear(_ animated: Bool) {
    yourTableView.deselectRow(at: selectedIndexPath, animated: true)
}

InSelectRowAtIndexPath: -

    func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: IndexPath) {
    selectedIndexPath = indexPath
}

0

यदि इसे छूने के बाद सेल बच जाता है, तो आप UITabelView विधि को कॉल कर सकते हैं,

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

`[tableView deselectRowAtIndexPath:indexPath animated:YES];`   

}

या, आप निम्न विधियों का उपयोग कर सकते हैं और इसे अपनी आवश्यकताओं के अनुसार संशोधित कर सकते हैं,

// MARK: UITableViewDelegate

func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath) {
  if let cell = tableView.cellForRowAtIndexPath(indexPath) {
     cell.backgroundColor = UIColor.greenColor()
  }
}

func tableView(tableView: UITableView, didUnhighlightRowAtIndexPath indexPath: NSIndexPath) {
  if let cell = tableView.cellForRowAtIndexPath(indexPath) {
     cell.backgroundColor = UIColor.blackColor()
  }
} 

0

Xcode 10, स्विफ्ट 4

मेरे पास यही मुद्दा था और मुझे पता चला कि मैंने अपने टेबल व्यू कॉन्ट्रोलर के निचले भाग में देखने के लिए एक खाली कॉल छोड़ा था। एक बार जब मैंने खाली ओवरराइड फ़ंक्शन को हटा दिया तो पंक्ति को तालिका दृश्य पर लौटने पर हाइलाइट नहीं किया गया।

समस्या दुर्गंध

override func viewWillAppear(_ animated: Bool) {
  // need to remove this function if not being used.
}

खाली समारोह को हटाने से मेरी समस्या हल हो गई।


0

स्विफ्ट 5 समाधान:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.