Mam UITableView
z 5 UITableViewCells
. Każda komórka zawiera UIButton
który jest ustawiony w następujący sposób:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:1];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell viewWithTag:1];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
Moje pytanie brzmi: w buttonPressedAction:
metodzie skąd mam wiedzieć, który przycisk został naciśnięty. Rozważałem użycie tagów, ale nie jestem pewien, czy to najlepsza trasa. Chciałbym móc jakoś oznaczyć ten indexPath
element sterujący.
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
// how do I know which button sent this message?
// processing button press for this row requires an indexPath.
}
Jaki jest standardowy sposób to zrobić?
Edytować:
W pewnym sensie rozwiązałem to, wykonując następujące czynności. Wciąż chciałbym mieć opinię, czy jest to standardowy sposób na zrobienie tego, czy jest lepszy sposób?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell.contentView.subviews objectAtIndex:0];
[button setTag:indexPath.row];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
int row = button.tag;
}
Ważne jest, aby zauważyć, że nie mogę ustawić znacznika podczas tworzenia komórki, ponieważ zamiast tego komórkę można usunąć z kolejki. Czuje się bardzo brudny. Musi być lepszy sposób.
ios
iphone
uitableview
uibutton
wodza
źródło
źródło
Odpowiedzi:
W przykładzie akcesoriów Apple używana jest następująca metoda:
Następnie w manipulatorze dotykowym pobrano współrzędną dotykową i od tej współrzędnej obliczana jest ścieżka indeksu:
źródło
Znalazłem metodę używania superwizji superwizji w celu uzyskania odniesienia do indeksu komórki Ścieżka działała idealnie. Dzięki iphonedevbook.com (macnsmith) za tekst linku do końcówki
źródło
Oto jak to robię. Prosty i zwięzły:
źródło
CGPointZero
zamiastCGPointMake(0, 0)
;-)Znalazłem dobre rozwiązanie tego problemu gdzie indziej, bez bałaganu dzięki tagom na przycisku:
źródło
buttonPressedAction:
alebuttonPressedAction:forEvent:
.Co powiesz na przesłanie informacji, tak jak
NSIndexPath
przyUIButton
użyciu zastrzyku środowiska wykonawczego.1) Potrzebujesz środowiska uruchomieniowego podczas importu
2) dodaj stałą statyczną
3) dodaj
NSIndexPath
do przycisku w czasie wykonywania, używając:(void) setMetaData: (id) target withObject: (id) newObj
4) po naciśnięciu przycisku pobierz metadane, używając:
(id) metaData: (id) cel
Cieszyć się
źródło
Odpowiedź na czyn (@Vladimir) jest szybka:
Chociaż sprawdzanie pod kątem
indexPath != nil
daje mi palec ... „NSIndexPath nie jest podtypem NSString”źródło
W Swift 4.2 i iOS 12 możesz wybrać jeden z 5 następujących kompletnych przykładów , aby rozwiązać problem.
# 1. Używanie
UIView
„convert(_:to:)
iUITableView
”indexPathForRow(at:)
# 2. Używanie
UIView
„convert(_:to:)
iUITableView
”indexPathForRow(at:)
(alternatywa)Jest to alternatywa dla poprzedniego przykładu, w którym przechodzimy
nil
dotarget
parametru waddTarget(_:action:for:)
. W ten sposób, jeśli pierwszy responder nie zaimplementuje akcji, zostanie wysłany do następnego respondera w łańcuchu respondentów, dopóki nie zostanie znaleziona poprawna implementacja.# 3. Korzystanie
UITableView
„sindexPath(for:)
i przenieść wzórW tym przykładzie ustawiliśmy kontroler widoku jako delegata komórki. Po naciśnięciu przycisku komórki uruchamia połączenie z odpowiednią metodą uczestnika.
# 4. Za pomocą
UITableView
„sindexPath(for:)
oraz zamknięcie dla delegacjiJest to alternatywa dla poprzedniego przykładu, w którym do obsługi naciśnięcia przycisku używamy zamknięcia zamiast deklaracji delegowania protokołu.
# 5. Korzystanie
UITableViewCell
zaccessoryType
iUITableViewDelegate
”tableView(_:accessoryButtonTappedForRowWith:)
Jeśli przycisk jest
UITableViewCell
„s standardowe wyposażenie sterowania, każdy z kranu na nim spowoduje wywołanieUITableViewDelegate
” stableView(_:accessoryButtonTappedForRowWith:)
, co pozwala uzyskać powiązany ścieżkę indeksu.źródło
źródło
Chciałbym użyć właściwości tagu, jak powiedziałeś, ustawiając tag tak:
następnie umieszczenie tagu w przycisku ButtonPressedAction w następujący sposób:
Lub
źródło
tag
jest liczbą całkowitą. trochę niezdarne jest kodowanie / dekodowanie ścieżek indeksu do znaczników widoku.Chociaż podoba mi się sposób tagowania ... jeśli nie chcesz używać tagów z jakiegokolwiek powodu, możesz utworzyć członka
NSArray
gotowych przycisków:następnie utwórz te przyciski przed renderowaniem tableView i wepchnij je do tablicy.
Następnie wewnątrz
tableView:cellForRowAtIndexPath:
funkcji możesz wykonać:Następnie w
buttonPressedAction:
funkcji możesz to zrobićźródło
OBSŁUGA SEKCJI - Przechowałem NSIndexPath w niestandardowym UITableViewCell
W CLKIndexPricesHEADERTableViewCell.xib
IN IB Dodaj UIButton do XIB - NIE dodawaj akcji!
Dodaj wylot @ właściwość (zachowaj, nieatomowy) IBOutlet UIButton * przyciskIndexSectionClose;
NIE CTRL + PRZECIĄGNIJ akcji w IB (wykonanej w kodzie poniżej)
In viewForHeaderInSection (powinien również działać dla cellForRow .... itd., Jeśli tabela ma tylko 1 sekcję)
... skorzystaj z sekcji, aby uzyskać dane dla swojej komórki
...wypełnij
UŻYTKOWNIK naciska przycisk DELETE na nagłówku sekcji i to wywołuje
W tym przykładzie dodałem przycisk Usuń, więc powinienem pokazać UIAlertView, aby to potwierdzić
Przechowuję sekcję i wprowadzam do słownika, przechowując informacje o sekcji w ivar w VC
źródło
źródło
Działa to również dla mnie, dzięki @Cocoanut
Znalazłem metodę używania superwizji superwizji w celu uzyskania odniesienia do indeksu komórki Ścieżka działała idealnie. Dzięki iphonedevbook.com (macnsmith) za tekst linku do końcówki
źródło
możesz użyć wzorca tagu:
źródło
Czy coś brakuje? Nie możesz po prostu użyć nadawcy do zidentyfikowania przycisku. Nadawca poda następujące informacje:
Następnie, jeśli chcesz zmienić właściwości przycisku, powiedz obraz tła, który właśnie przekazujesz nadawcy:
Jeśli potrzebujesz tagu, metoda ACBurk jest w porządku.
źródło
Właściwie całkiem proste:
Działa dla mnie dobrze: P
jeśli chcesz dostosować ustawienia akcji docelowej, możesz uwzględnić parametr zdarzenia w metodzie, a następnie użyć akcentów tego zdarzenia, aby ustalić współrzędne dotyku. Współrzędne nadal wymagają rozwiązania w granicach widoku dotykowego, ale dla niektórych osób może to wydawać się łatwiejsze.
źródło
utwórz tablicę nsmutable i umieść w niej wszystkie przyciski usint [array addObject: yourButton];
w metodzie naciśnięcia przycisku
-
źródło
Niewielka zmiana odpowiedzi Cocoanuts (która pomogła mi rozwiązać ten problem), gdy przycisk znajdował się w stopce tabeli (co uniemożliwia znalezienie „klikniętej komórki”):
źródło
Zawsze używam tagów.
Musisz podklasować
UITableviewCell
i obsługiwać naciśnięcie przycisku stamtąd.źródło
To proste; utwórz niestandardową komórkę i wyjmij guzik
zmień identyfikator w powyższej metodzie na
(UIButton *)
Możesz uzyskać wartość, którą przycisk jest naciskany, wykonując sender.tag.
źródło
Podklasuj przycisk, aby zapisać wymaganą wartość, może utworzyć protokół (ControlWithData lub coś takiego). Ustaw wartość po dodaniu przycisku do komórki widoku tabeli. W zdarzeniu retuszu sprawdź, czy nadawca przestrzega protokołu i wyodrębnij dane. Zwykle przechowuję odwołanie do rzeczywistego obiektu renderowanego w komórce widoku tabeli.
źródło
AKTUALIZACJA SWIFT 2
Oto, jak dowiedzieć się, który przycisk został naciśnięty + wysłać dane do innego ViewController z tego przycisku,
indexPath.row
ponieważ zakładam, że o to chodzi w większości!Dla tych, którzy używają klasy ViewController i dodali tableView, używam ViewController zamiast TableViewController, więc ręcznie dodałem tableView, aby uzyskać do niego dostęp.
Oto kod do przekazywania danych do innego VC po dotknięciu tego przycisku i przekazaniu komórek
indexPath.row
źródło
Uwaga: używam niestandardowej komórki, ten kod działa dla mnie idealnie
źródło
Rozwiązanie Chrisa Schwerdta, ale wtedy w Swift działało dla mnie:
źródło
Ten problem składa się z dwóch części:
1) Uzyskanie
UITableViewCell
wciśniętej ścieżki indeksuUIButton
Istnieje kilka sugestii, takich jak:
Aktualizacja
UIButton
dydaktycznegotag
wcellForRowAtIndexPath:
sposób stosując ścieżkę indeksu możerow
wartość. To nie jest dobre rozwiązanie, ponieważ wymagatag
ciągłej aktualizacji i nie działa z widokami tabel z więcej niż jedną sekcją.Dodawanie
NSIndexPath
właściwość niestandardową komórki i jej uaktualnianie zamiastUIButton
„stag
wcellForRowAtIndexPath:
metodzie. Rozwiązuje to problem z wieloma sekcjami, ale nadal nie jest dobry, ponieważ wymaga zawsze aktualizacji.Utrzymywanie słabego refrenu nadrzędnego
UITableView
w niestandardowej komórce podczas jej tworzenia i używanieindexPathForCell:
metody w celu uzyskania ścieżki indeksu. Wydaje się nieco lepiej, nie trzeba niczego aktualizować wcellForRowAtIndexPath:
metodzie, ale nadal wymaga ustawienia słabego odwołania podczas tworzenia komórki niestandardowej.Korzystanie z
superView
właściwości komórki w celu uzyskania odwołania do elementu nadrzędnegoUITableView
. Nie ma potrzeby dodawania żadnych właściwości do niestandardowej komórki i nie trzeba niczego ustawiać / aktualizować podczas tworzenia / później. Ale komórkasuperView
zależy od szczegółów implementacji iOS. Dlatego nie można go używać bezpośrednio.Ale można to osiągnąć za pomocą prostej pętli, ponieważ jesteśmy pewni, że komórka, o której mowa, musi znajdować się w UITableView:
Tak więc te sugestie można połączyć w prostą i bezpieczną niestandardową metodę komórki do uzyskania ścieżki indeksu:
Odtąd ta metoda może być używana do wykrywania, który
UIButton
zostanie naciśnięty.2) Informowanie innych stron o zdarzeniu naciśnięcia przycisku
Po wewnętrznym poznaniu, w którym
UIButton
naciśnięto komórkę niestandardową z dokładną ścieżką indeksu, informacje te należy przesłać innym podmiotom (najprawdopodobniej kontrolerowi obsługiUITableView
). Tak więc zdarzenie kliknięcia przycisku może być obsługiwane na poziomie abstrakcyjnym i logicznym podobnym dodidSelectRowAtIndexPath:
metody delegowania UITableView.W tym celu można zastosować dwa podejścia:
a) Delegowanie: komórka niestandardowa może mieć
delegate
właściwość i może definiować protokół. Po naciśnięciu przycisku po prostu wykonuje swoje metody delegowania na swojejdelegate
właściwości. Ale tędelegate
właściwość należy ustawić dla każdej niestandardowej komórki podczas ich tworzenia. Alternatywnie komórka niestandardowa może również wykonywać swoje metody delegowania w widoku tabeli nadrzędnejdelegate
.b) Centrum powiadomień: niestandardowe komórki mogą zdefiniować niestandardową nazwę powiadomienia i opublikować to powiadomienie, podając w indeksie ścieżkę indeksu i informacje o widoku tabeli nadrzędnej
userInfo
. Nie trzeba niczego ustawiać dla każdej komórki, wystarczy tylko dodać obserwatora do powiadomienia komórki niestandardowej.źródło
Korzystam z rozwiązania, które podklasę,
UIButton
i pomyślałem, że powinienem je tutaj udostępnić, kody w Swift:Następnie pamiętaj, aby zaktualizować jego indexPath w
cellForRow(at:)
Tak więc, odpowiadając na zdarzenie przycisku, możesz go używać w podobny sposób
źródło