2010-05-19 10 views
22

Mam widok tabeli, gdzie każda komórka ma widok akcesoriów przycisku. Tabela jest zarządzana przez pobrany kontroler wyników i często jest zmieniana. Chcę móc nacisnąć jeden z przycisków i uzyskać ścieżkę indeksu komórki widoku tabeli tego przycisku. Próbowałem to zrobić przez kilka dni, przechowując wiersz przycisku w jego znaczniku, ale kiedy tabela zostanie zmieniona, wiersz staje się niepoprawny i ciągle nie mogę poprawnie zmienić kolejność znaczników. Jakieś nowe pomysły, jak śledzić ścieżkę indeksu komórki przycisku?Jak mogę śledzić ścieżkę indeksu przycisku w komórce widoku tabeli?

+0

Możliwy duplikat [Sprawdzenie, które UIButton został naciśnięty w UITableView] (http://stackoverflow.com/questions/1802707/detecting-which-uibutton-was-pressed-in-a-uitableview) – lukaivicev

Odpowiedz

4

Stworzyłem jedną metodę uzyskania indexPath, Hope to ci pomoże.

Utwórz przycisk akcji (aMethod :) w cellForRowAtIndexPath

-(void) aMethod:(UIButton *)sender 
{ 
    // Calling Magic Method which will return us indexPath. 
    NSIndexPath *indexPath = [self getButtonIndexPath:sender]; 

    NSLog(@"IndexPath: %li", indexPath.row); 
    NSLog(@"IndexRow: %li", indexPath.section); 
} 

// Tutaj jest metoda Magia uzyskania Buttona za indexPath

-(NSIndexPath *) getButtonIndexPath:(UIButton *) button 
{ 
    CGRect buttonFrame = [button convertRect:button.bounds toView:groupTable]; 
    return [groupTable indexPathForRowAtPoint:buttonFrame.origin]; 
} 
25

To przestało działać z iOS 7; sprawdź Mike Weller's answer zamiast

- (IBAction)clickedButton:(id)sender { 
    UIButton *button = (UIButton *)sender; 
    UITableViewCell *cell = (UITableViewCell *)button.superview; 
    UITableView *tableView = (UITableView *)cell.superview; 
    NSIndexPath *indexPath = [tableView indexPathForCell:cell]; 
} 

lub krótszy:

- (IBAction)clickedButton:(id)sender { 
    NSIndexPath *indexPath = [(UITableView *)sender.superview.superview indexPathForCell:(UITableViewCell *)sender.superview]; 
} 

Oba są niesprawdzone!

+0

Dzięki tak dużo ! To naprawiło problem i teraz mogę w końcu ruszyć dalej :) Dla tych, którzy dostają się tu później i chcą to zaimplementować, w pierwszym przykładzie potrzebujesz jednego mniejszego wywołania superview, aby uzyskać UITableViewCell, a superview jest pisane małymi literami. W przeciwnym razie wszystko jest idealne (nie próbowałem tego krótszego przykładu). – Jake

+0

Masz rację, zredagowałem moją odpowiedź;) Moja logika za 2 '.superviews', aby uzyskać' UITableViewCell': komórka to 'superview'' accessView' który jest 'superview'' UIButton' . Ale myślę, że się pomyliłem. –

+0

dziękuję youuuuuu :) – cV2

9

Nie wiem, dlaczego muszę dwukrotnie wywołać metodę superview, aby uzyskać UITableViewCell.

Aktualizacja:

podziękować za Qiulang, teraz mam go.

"To dlatego, że SDK dodał teraz prywatną klasę o nazwie UITableViewCellContentView dla UITableViewCell, która jest teraz przeglądarką przycisku." - Qiulang

UIButton *button = (UIButton *)sender; 
UITableViewCell *cell = (UITableViewCell *)button.superview.superview; 
UITableView *curTableView = (UITableView *)cell.superview; 
NSIndexPath *indexPath = [curTableView indexPathForCell:cell]; 
+3

To dlatego, że SDK dodał teraz prywatną klasę o nazwie UITableViewCellContentView dla UITableViewCell, która jest teraz przeglądarką przycisku. – Qiulang

+0

Dzięki za to. Life Saver, upvote :) – jhilgert00

31

Jeśli czujesz się nieswojo powołując się na button.superview, metoda ta powinna być nieco bardziej wytrzymałe niż w niektórych innych odpowiedzi tutaj:

UIButton *button = (UIButton *)sender; 
CGRect buttonFrame = [button convertRect:button.bounds toView:self.tableView]; 
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonFrame.origin]; 
+0

najlepsza odpowiedź, pomógł –

21

wspina się oglądać hierarchie z .superview (jak wszystkie istniejące odpowiedzi pokazują) jest naprawdę złym sposobem robienia rzeczy. Jeśli zmieni się struktura UITableViewCell (co miało miejsce wcześniej), twoja aplikacja się zepsuje. Wyświetlanie w kodzie .superview.superview powinno uruchamiać dzwonki alarmowe.

Przycisk i jego przewodnik należy dodać do niestandardowej podklasy UITableViewCell i tam umieścić. Tam właśnie należy.

Podklasa komórek może następnie przekazać zdarzenie przycisku przez standardowy interfejs pełnomocnika lub blok. Należy dążyć do czegoś takiego:

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    MyCustomCell *cell = ...; 

    // ... 

    cell.onButtonTapped = ^{ 
     [self buttonSelectedAtIndexPath:indexPath]; 
    } 

    // OR 

    cell.delegate = self; 

    // ... 
} 

(uwaga: jeśli przejdziesz drogę bloku, trzeba będzie użyć odwołania __weak siebie, aby zapobiec zachować cykli, ale myślałem, że będzie zaśmiecać przykład).

Zażycie trasę delegata byś wtedy tę metodę delegata do realizacji:

- (void)cellButtonPressed:(UITableViewCell *)cell 
{ 
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; 
    // ... 
} 

Twój kod ma teraz pełny dostęp do odpowiedniego kontekstu, gdy obsługuje zdarzenie.

Implementacja tego interfejsu w klasie komórkowej powinna być prosta.

6

Miałem ten sam problem również i zbudowałem prostą metodę rekurencyjną, która działa bez względu na to, ile wyświetleń jest głęboko kontrolowanych.

-(NSIndexPath*)GetIndexPathFromSender:(id)sender{ 

    if(!sender) { return nil; } 

    if([sender isKindOfClass:[UITableViewCell class]]) 
    { 
     UITableViewCell *cell = sender; 
     return [self.tableView indexPathForCell:cell]; 
    } 

    return [self GetIndexPathFromSender:((UIView*)[sender superview])]; 
} 


-(void)ButtonClicked:(id)sender{ 
    NSIndexPath *indexPath = [self GetIndexPathFromSender:sender]; 
} 
+0

Ostrożnie dla nieskończonej rekurencji ... Prawdopodobnie dodalbym właz ucieczki na górze tej metody, aby być bezpiecznym: 'if (! Sender) {return nil; } ' – wxactly

+0

Dobra rada nadeszła ... Dokonałem zmiany. Dzięki! – 1kmonkies

+0

tą metodą getIndexPathFromSender jest Grrrrrreat! –

3

Użyj tego Perfect działa dla mnie.

CGPoint center= [sender center]; 
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1]; 
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint]; 
NSLog(@"%@",indexPath); 
2

SWIFT 2 UPDATE

Oto jak dowiedzieć się, który przycisk został użyty

@IBAction func yourButton(sender: AnyObject) { 


var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView) 
    let indexPath = self.tableView.indexPathForRowAtPoint(position) 
    let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as 
    UITableViewCell 
    print(indexPath?.row) 
    print("Tap tap tap tap") 

} 
Powiązane problemy