बटन प्रेस पर UITableView सेल की पंक्ति हो रही है


84

मेरे पास एक टेबलव्यू कंट्रोलर है जो कोशिकाओं की एक पंक्ति प्रदर्शित करता है। प्रत्येक सेल में 3 बटन होते हैं। मैंने प्रत्येक सेल के लिए 1,2,3 होने के लिए टैग गिने हैं। समस्या यह है कि मैं नहीं जानता कि किस सेल पर एक बटन दबाया जा रहा है। मैं वर्तमान में केवल प्रेषक का टैग प्राप्त कर रहा हूं जब किसी एक बटन को दबाया गया हो। क्या बटन दबाने पर सेल पंक्ति संख्या प्राप्त करने का कोई तरीका है?

जवाबों:


278

आपको वास्तव में इस विधि का उपयोग करना चाहिए:

CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];

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

let buttonPosition = sender.convert(CGPoint(), to:tableView)
let indexPath = tableView.indexPathForRow(at:buttonPosition)

यह आपको indexPathउस बटन की स्थिति के आधार पर देगा जिसे दबाया गया था। cellForRowAtIndexPathयदि आपको सेल की आवश्यकता है या indexPath.rowयदि आपको पंक्ति संख्या की आवश्यकता है तो आप अभी कॉल करेंगे ।

यदि आप पागल हैं, तो आप टेबल व्यू पर उस बिंदु के लिए नहीं if (indexPath) ...मिलने की स्थिति में इसे इस्तेमाल करने से पहले जांच सकते indexPathहैं।

यदि Apple ने व्यू स्ट्रक्चर को बदलने का निर्णय लिया है तो अन्य सभी उत्तरों के टूटने की संभावना है।


8
यह एक लाख बार। दूसरों में से किसी ने भी काम नहीं किया, लेकिन यह एकदम सही था और अब तक का सबसे सरल उपाय है
ine

2
यह उत्तर काम करता है क्योंकि यह सही समाधान है। दूसरे कामचलाऊ हैं। धन्यवाद!
ब्रूनो फिलिप

1
यदि आपके पास self.tableview नहीं है , तो कृपया इस पृष्ठ पर मेरे उत्तर को देखें।
अशोक

1
एक बार जब मुझे पता चला कि मेरे प्रेषक को गलत कक्षा है, तो यह मेरे लिए काम कर रहा है। फिक्स्ड यह UIButton दबाया जा सकता है, और अब यह काम कर रहा है!
lordB8r

1
बस याद रखना विधि convertPoint:*to*Viewनहीं है convertPoint:*from*View। मैं Xcode स्वत: पूर्ण इस्तेमाल किया और fromView विधि केवल काम नहीं कर रहा करने के लिए अग्रणी के साथ समाप्त हो गया ...
tGilani

40

संपादित करें: यह उत्तर पुराना है। कृपया इस विधि का उपयोग करें


इसे इस्तेमाल करे:

-(void)button1Tapped:(id)sender
{
    UIButton *senderButton = (UIButton *)sender;
    UITableViewCell *buttonCell = (UITableViewCell *)[senderButton superview];
    UITableView* table = (UITableView *)[buttonCell superview];
    NSIndexPath* pathOfTheCell = [table indexPathForCell:buttonCell];
    NSInteger rowOfTheCell = [pathOfTheCell row];
    NSLog(@"rowofthecell %d", rowOfTheCell);
}

संपादित करें: यदि आप contentView का उपयोग कर रहे हैं, तो इसके बजाय बटनकाेल का उपयोग करें:

UITableViewCell *buttonCell = (UITableViewCell *)senderButton.superview.superview;

1
आप सेल में ही नहीं, बल्कि उसकी contentViewप्रॉपर्टी में भी सबव्यू देने वाले हैं - इसलिए यह समाधान वास्तव में काम नहीं करता है।

1
मैं @ H2CO3 से सहमत हूं और मुझे भी नहीं लगता कि यह पर्यवेक्षण पर्यवेक्षकों को संदर्भित करके किया जाना चाहिए। कृपया नीचे एक बेहतर तरीका देखें: stackoverflow.com/a/16270198/308315
iwasrobbed

@minimalpop क्या आप सही उत्तर बदल सकते हैं? एक बेहतर क्यू / ए है!
थॉमस बेस्नेहर्ड

यह iOS 7 में काम नहीं करता है। indexPathForRowAtPoint का उपयोग करें: नीचे उत्तर दें
ऑस्टिन

मैंने UICollectionView के साथ एक ही संस्करण की कोशिश की और पूरी तरह से काम करता है। आपका बहुत बहुत धन्यवाद!
क्लॉस

18

मैं इस तरह से सेल के indexPath लाने की सलाह दूंगा, जिसमें कोई भी कस्टम सबव्यू हो - ( iOS 7 और साथ ही पिछले सभी संस्करणों के साथ )

-(void)button1Tapped:(id)sender {
//- (void)cellSubviewTapped:(UIGestureRecognizer *)gestureRecognizer {
//    UIView *parentCell = gestureRecognizer.view.superview;
    UIView *parentCell = sender.superview;

    while (![parentCell isKindOfClass:[UITableViewCell class]]) {   // iOS 7 onwards the table cell hierachy has changed.
        parentCell = parentCell.superview;
    }

    UIView *parentView = parentCell.superview;

    while (![parentView isKindOfClass:[UITableView class]]) {   // iOS 7 onwards the table cell hierachy has changed.
        parentView = parentView.superview;
    }


    UITableView *tableView = (UITableView *)parentView;
    NSIndexPath *indexPath = [tableView indexPathForCell:(UITableViewCell *)parentCell];

    NSLog(@"indexPath = %@", indexPath);
}

यह भी आवश्यकता नहीं है self.tablview

इसके अलावा, टिप्पणी कोड को नोट करें जो आपके कस्टम सबव्यू में जोड़े गए UIGestureRecognizer के एक @selector के माध्यम से समान है, तो उपयोगी है।


क्या होगा अगर मुझे यूटिटेवेसकंट्रोलर में पाए जाने वाले डेटा की आवश्यकता है?
इओसमेंटलिस्ट

अच्छा जवाब। यदि आपके पास एक खोज पट्टी है और जानना चाहेंगे कि इस समय आप किस तालिका का उपयोग करते हैं।
सूरज के थॉमस

टेबल सेल पदानुक्रम बदल गया? क्या आप मुझे यह समझने में मदद कर सकते हैं कि क्या बदलाव हुआ है और क्या यह आगे भी बदल सकता है?
कमलदीप सिंह भाटिया 10

3

इसके दो तरीके हैं:

  1. @ H2CO3 सही है। आप ऐसा कर सकते हैं जो @ user523234 ने सुझाव दिया, लेकिन एक छोटे से बदलाव के साथ, UITableViewCellContentView का सम्मान करने के लिए जो UIButton और UITableViewCell के बीच में आना चाहिए। तो उसके कोड को संशोधित करने के लिए:

    - (IBAction)button1Tapped:(id)sender
    {
        UIButton *senderButton = (UIButton *)sender;
        UITableViewCellContentView *cellContentView = (UITableViewCellContentView *)senderButton.superview;
        UITableViewCell *tableViewCell = (UITableViewCell *)cellContentView.superview;
        UITableView* tableView = (UITableView *)tableViewCell.superview;
        NSIndexPath* pathOfTheCell = [tableView indexPathForCell:tableViewCell];
        NSInteger rowOfTheCell = pathOfTheCell.row;
        NSLog(@"rowofthecell %d", rowOfTheCell);
    }
    
  2. यदि आप एक कस्टम UITableViewCell (अपना उपवर्ग) बनाते हैं, तो आप बस selfIBA में कॉल कर सकते हैं । जब आप सेल सेट करते हैं तो आप स्टोरीबोर्ड या प्रोग्रामेटिक रूप से IBAction फ़ंक्शन को अपने बटन से लिंक कर सकते हैं।

    - (IBAction)button1Tapped:(id)sender
    {
        UITableView* tableView = (UITableView *)self.superview;
        NSIndexPath* pathOfTheCell = [tableView indexPathForCell:self];
        NSInteger rowOfTheCell = pathOfTheCell.row;
        NSLog(@"rowofthecell %d", rowOfTheCell);
    }
    

2

मैं तुम्हें में सेल बटन जोड़ने मान cellForRowAtIndexPathहै, तो मैं क्या होगा एक कस्टम वर्ग उपवर्ग बनाने के लिए है UIButton, एक जोड़ने टैग कहा जाता है rowNumber, और संलग्न जाने वाले डेटा को सेल करने के लिए बटन को जोड़ते समय।


3
यह ठीक है, लेकिन इसके लिए एक उपवर्ग बनाने का कोई कारण नहीं UIButtonहै। tagकी एक आम संपत्ति है UIView
रोब नेपियर

पता नहीं मैं क्या सोच रहा था और मान यूआई कुछ एक नहीं है यूआई , सुधार के लिए धन्यवाद!
डेरेक ली

2

एक और सरल तरीका:

  • तालिका में टच का बिंदु प्राप्त करें

  • फिर बिंदु पर सेल का सूचकांक पथ प्राप्त करें

  • अनुक्रमणिका पथ में पंक्ति अनुक्रमणिका होती है

कोड है:

- (void)buttonTapped:(id)sender {
    UITapGestureRecognizer *tap = (UITapGestureRecognizer *)sender;
    CGPoint point = [tap locationInView:theTableView];

    NSIndexPath *theIndexPath = [theTableView indexPathForRowAtPoint:point];

    NSInteger theRowIndex = theIndexPath.row;
    // do your stuff here
    // ...
}

1

स्विफ्ट 3

नोट: यह वास्तव में ऊपर दिए गए स्वीकृत उत्तर में जाना चाहिए , सिवाय इसके कि मेटा इस तरह के संपादनों पर निर्भर करता है।

@IBAction func doSomething(_ sender: UIButton) {
   let buttonPosition = sender.convert(CGPoint(), to: tableView)
   let index = tableView.indexPathForRow(at: buttonPosition)
}

दो छोटी टिप्पणियाँ:

  1. डिफ़ॉल्ट फ़ंक्शन में प्रेषक प्रकार कोई भी होता है, जिसमें कनवर्ट नहीं होता है।
  2. CGPointZero को CGPoint () द्वारा प्रतिस्थापित किया जा सकता है

अच्छी तरह से काम।

0

एक समाधान बटन के पर्यवेक्षण के टैग या दृश्य पदानुक्रम (यदि बटन सेल की सामग्री दृश्य में है) में अधिक हो सकता है।


0

मैं स्विफ्ट में कोड साझा करना चाहूंगा -

extension UITableView
{
    func indexPathForCellContainingView(view1:UIView?)->NSIndexPath?
    {
        var view = view1;
        while view != nil {
            if (view?.isKindOfClass(UITableViewCell) == true)
            {
                return self.indexPathForCell(view as! UITableViewCell)!
            }
            else
            {
                view = view?.superview;
            }
        }
        return nil
    }
}

0

स्विफ्ट में:

@IBAction func buttonAction(_ sender: UIButton) {
    guard let indexPath = tableView.indexPathForRow(at: sender.convert(CGPoint(), to: tableView)) else {
        return
    }
    // do something
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.