Wykrywanie, który UIButton został naciśnięty w widoku UITableView
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 Jest Takie: w metodzie buttonPressedAction:
, skąd mam wiedzieć, który przycisk został naciśnięty. Rozważałem użycie tagów, ale nie jestem pewien, czy jest to najlepsza trasa. Chciałbym móc jakoś przypisać indexPath
do kontrolki.
- (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 na to?
Edit:
Rozwiązałem to, wykonując następujące czynności. Nadal chciałbym mieć opinia, czy jest to standardowy sposób, 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 pamiętać, że nie mogę ustawić tagu w tworzeniu komórki, ponieważ komórka może zostać usunięta. Czuję się bardzo brudny. Musi być lepszy sposób.
26 answers
W próbce Apple ' a stosuje się następującą metodę:
[button addTarget:self action:@selector(checkButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
Następnie w touch handler pobierana jest współrzędna dotykowa, a ścieżka indeksu jest obliczana z tej współrzędnej:
- (void)checkButtonTapped:(id)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
if (indexPath != nil)
{
...
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-29 13:39:14
Odkryłem, że metoda wykorzystania superview ' s superview do uzyskania odniesienia do ścieżki indeksowej komórki działała idealnie. Dzięki iphonedevbook.com dla końcówki link text
-(void)buttonPressed:(id)sender {
UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
NSIndexPath *clickedButtonPath = [self.tableView indexPathForCell:clickedCell];
...
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-06 02:54:37
Oto Jak to robię. Proste i zwięzłe:
- (IBAction)buttonTappedAction:(id)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero
toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-30 10:33:52
Znalazłem fajne rozwiązanie tego problemu gdzie indziej, bez bałaganu z tagami na przycisku:
- (void)buttonPressedAction:(id)sender {
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
do stuff with the indexPath...
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-10 23:32:15
Jak o wysyłanie informacji jak {[1] } w UIButton
za pomocą runtime injection.
1) potrzebujesz runtime przy imporcie
2) Dodaj stałą statyczną
3) dodaj NSIndexPath
do przycisku w runtime używając:
(void) setMetaData: (id)target withObject: (id)newObj
4) po naciśnięciu przycisku Pobierz metadane za pomocą:
(id) metadane: (id)target
Enjoy
#import <objc/runtime.h>
static char const * const kMetaDic = "kMetaDic";
#pragma mark - Getters / Setters
- (id)metaData:(id)target {
return objc_getAssociatedObject(target, kMetaDic);
}
- (void)setMetaData:(id)target withObject:(id)newObj {
objc_setAssociatedObject(target, kMetaDic, newObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#On the cell constructor
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
....
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
....
[btnSocial addTarget:self
action:@selector(openComments:)
forControlEvents:UIControlEventTouchUpInside];
#add the indexpath here or another object
[self setMetaData:btnSocial withObject:indexPath];
....
}
#The action after button been press:
- (IBAction)openComments:(UIButton*)sender{
NSIndexPath *indexPath = [self metaData:sender];
NSLog(@"indexPath: %d", indexPath.row);
//Reuse your indexpath Now
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-01 05:00:30
func buttonAction(sender:UIButton!)
{
var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tablevw)
let indexPath = self.tablevw.indexPathForRowAtPoint(position)
let cell: TableViewCell = tablevw.cellForRowAtIndexPath(indexPath!) as TableViewCell
println(indexPath?.row)
println("Button tapped")
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-31 05:58:11
To do (@Vladimir)'s answer is Swift:
var buttonPosition = sender.convertPoint(CGPointZero, toView: self.tableView)
var indexPath = self.tableView.indexPathForRowAtPoint(buttonPosition)!
/ Align = "center" bgcolor = "# e0ffe0 " / cesarz chin / / align = center / .."NSIndexPath nie jest podtypem NSString"Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-24 16:27:59
Użyłbym właściwości tag, tak jak powiedziałeś, ustawiając tag w ten sposób:
[button setTag:indexPath.row];
Następnie uzyskanie znacznika wewnątrz buttonPressedAction tak:
((UIButton *)sender).tag
Lub
UIButton *button = (UIButton *)sender;
button.tag;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-26 10:16:38
Chociaż podoba mi się sposób tagowania... jeśli nie chcesz używać tagów z jakiegokolwiek powodu,
możesz utworzyć member NSArray
premade buttons:
NSArray* buttons ;
Następnie utwórz te przyciski przed renderowaniem widoku tableView i wciśnij je do tablicy.
Następnie wewnątrz funkcji tableView:cellForRowAtIndexPath:
możesz wykonać:
UIButton* button = [buttons objectAtIndex:[indexPath row] ] ;
[cell.contentView addSubview:button];
Następnie w funkcji buttonPressedAction:
można wykonać
- (void)buttonPressedAction:(id)sender {
UIButton* button = (UIButton*)sender ;
int row = [buttons indexOfObject:button] ;
// Do magic
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-01 05:00:59
Do obsługi sekcji-zapisałem NSIndexPath w niestandardowym UITableViewCell
W CLKIndexPricesHEADERTableViewCell.xib
IN Ib Add UIButton to XIB-DONT add action!
Add outlet @property (retain, nonatomic) Iboutlet UIButton *buttonIndexSectionClose;
Nie CTRL + przeciągaj akcji w IB (wykonanej w kodzie poniżej)
@interface CLKIndexPricesHEADERTableViewCell : UITableViewCell
...
@property (retain, nonatomic) IBOutlet UIButton *buttonIndexSectionClose;
@property (nonatomic, retain) NSIndexPath * indexPathForCell;
@end
In viewForHeaderInSection (powinno działać również dla cellForRow.... etc jeśli tabela ma tylko 1 sekcję)
- viewForHeaderInSection is called for each section 1...2...3
- get the cell CLKIndexPricesHEADERTableViewCell
- getTableRowHEADER just does the normal dequeueReusableCellWithIdentifier
- STORE the indexPath IN the UITableView cell
- indexPath.section = (NSInteger)section
- indexPath.row = 0 always (we are only interested in sections)
- (UIView *) tableView:(UITableView *)tableView1 viewForHeaderInSection:(NSInteger)section {
//Standard method for getting a UITableViewCell
CLKIndexPricesHEADERTableViewCell * cellHEADER = [self getTableRowHEADER];
...użyj sekcja pobierania danych dla komórki
...fill it in
indexName = ffaIndex.routeCode;
indexPrice = ffaIndex.indexValue;
//
[cellHEADER.buttonIndexSectionClose addTarget:self
action:@selector(buttonDELETEINDEXPressedAction:forEvent:)
forControlEvents:UIControlEventTouchUpInside];
cellHEADER.indexPathForCell = [NSIndexPath indexPathForRow:0 inSection:section];
return cellHEADER;
}
Użytkownik naciska przycisk DELETE na nagłówku sekcji i wywoła
- (void)buttonDELETEINDEXPressedAction:(id)sender forEvent:(UIEvent *)event
{
NSLog(@"%s", __PRETTY_FUNCTION__);
UIView * parent1 = [sender superview]; // UiTableViewCellContentView
//UIView *myContentView = (UIView *)parent1;
UIView * parent2 = [parent1 superview]; // custom cell containing the content view
//UIView * parent3 = [parent2 superview]; // UITableView containing the cell
//UIView * parent4 = [parent3 superview]; // UIView containing the table
if([parent2 isMemberOfClass:[CLKIndexPricesHEADERTableViewCell class]]){
CLKIndexPricesHEADERTableViewCell *myTableCell = (CLKIndexPricesHEADERTableViewCell *)parent2;
//UITableView *myTable = (UITableView *)parent3;
//UIView *mainView = (UIView *)parent4;
NSLog(@"%s indexPath.section,row[%d,%d]", __PRETTY_FUNCTION__, myTableCell.indexPathForCell.section,myTableCell.indexPathForCell.row);
NSString *key = [self.sortedKeysArray objectAtIndex:myTableCell.indexPathForCell.section];
if(key){
NSLog(@"%s DELETE object at key:%@", __PRETTY_FUNCTION__,key);
self.keyForSectionIndexToDelete = key;
self.sectionIndexToDelete = myTableCell.indexPathForCell.section;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Remove Index"
message:@"Are you sure"
delegate:self
cancelButtonTitle:@"No"
otherButtonTitles:@"Yes", nil];
alertView.tag = kALERTVIEW_REMOVE_ONE_INDEX;
[alertView show];
[alertView release];
//------
}else{
NSLog(@"ERROR: [%s] key is nil for section:%d", __PRETTY_FUNCTION__,myTableCell.indexPathForCell.section);
}
}else{
NSLog(@"ERROR: [%s] CLKIndexPricesHEADERTableViewCell not found", __PRETTY_FUNCTION__);
}
}
W tym przykładzie dodałem przycisk Usuń, więc powinien pokazać UIAlertView, aby to potwierdzić
Zapisuję sekcję i klucz do słownika przechowując informacje o sekcji w ivar w VC
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(alertView.tag == kALERTVIEW_REMOVE_ONE_INDEX){
if(buttonIndex==0){
//NO
NSLog(@"[%s] BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex);
//do nothing
}
else if(buttonIndex==1){
//YES
NSLog(@"[%s] BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex);
if(self.keyForSectionIndexToDelete != nil){
//Remove the section by key
[self.indexPricesDictionary removeObjectForKey:self.keyForSectionIndexToDelete];
//sort the keys so sections appear alphabetically/numbericsearch (minus the one we just removed)
[self updateTheSortedKeysArray];
//Delete the section from the table using animation
[self.tableView beginUpdates];
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:self.sectionIndexToDelete]
withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
//required to trigger refresh of myTableCell.indexPathForCell else old values in UITableViewCells
[self.tableView reloadData];
}else{
NSLog(@"ERROR: [%s] OBJECT is nil", __PRETTY_FUNCTION__);
}
}
else {
NSLog(@"ERROR: [%s] UNHANDLED BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex);
}
}else {
NSLog(@"ERROR: [%s] unhandled ALERTVIEW TAG:%d", __PRETTY_FUNCTION__,alertView.tag);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-11 14:58:41
A better way would be to subclass your button and add a indexPath property to it.
//Implement a subclass for UIButton.
@interface NewButton:UIButton
@property(nonatomic, strong) NSIndexPath *indexPath;
Make your button of type NewButton in the XIB or in the code whereever you are initializing them.
Then in the cellForRowAtIndexPath put the following line of code.
button.indexPath = indexPath;
return cell; //As usual
Now in your IBAction
-(IBAction)buttonClicked:(id)sender{
NewButton *button = (NewButton *)sender;
//Now access the indexPath by buttons property..
NSIndexPath *indexPath = button.indexPath; //:)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-19 08:06:31
To działa dla mnie równie dobrze, dzięki @ Cocoanut
Odkryłem, że metoda wykorzystania superview ' s superview do uzyskania odniesienia do ścieżki indeksowej komórki działała idealnie. Dzięki iphonedevbook.com (macnsmith) for the tip link text
-(void)buttonPressed:(id)sender {
UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
NSIndexPath *clickedButtonPath = [self.tableView indexPathForCell:clickedCell];
...
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-07 12:11:17
Możesz użyć wzoru znacznika:
- (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:[indexPath row]]; //use the row as the current tag
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell viewWithTag:[indexPath row]]; //use [indexPath row]
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
//button.tag has the row number (you can convert it to indexPath)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-26 10:16:46
Czy coś przeoczyłem? Nie możesz użyć nadawcy do identyfikacji przycisku. Nadawca poda ci takie informacje:
<UIButton: 0x4b95c10; frame = (246 26; 30 30); opaque = NO; tag = 104; layer = <CALayer: 0x4b95be0>>
Następnie, jeśli chcesz zmienić właściwości przycisku, powiedz obraz tła, po prostu powiedz nadawcy:
[sender setBackgroundImage:[UIImage imageNamed:@"new-image.png"] forState:UIControlStateNormal];
Jeśli potrzebujesz tagu, metoda Acburka jest w porządku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-22 22:48:41
// how do I know which button sent this message?
// processing button press for this row requires an indexPath.
Całkiem proste:
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
CGPoint rowButtonCenterInTableView = [[rowButton superview] convertPoint:rowButton.center toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rowButtonCenterInTableView];
MyTableViewItem *rowItem = [self.itemsArray objectAtIndex:indexPath.row];
// Now you're good to go.. do what the intention of the button is, but with
// the context of the "row item" that the button belongs to
[self performFooWithItem:rowItem];
}
Działa dobrze dla mnie: P
Jeśli chcesz dostosować ustawienia działania docelowego, możesz dołączyć parametr zdarzenia do metody, a następnie użyć dotknięć tego zdarzenia, aby rozwiązać współrzędne dotknięcia. Współrzędne nadal muszą być rozwiązane w granicach widoku dotykowego, ale może to wydawać się łatwiejsze dla niektórych osób.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-14 02:24:02
Utwórz tablicę nsmutable i umieść przycisk all w tej tablicy usint [array addObject:yourButton];
W metodzie naciśnięcia przycisku
-
(void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
for(int i=0;i<[yourArray count];i++){
if([buton isEqual:[yourArray objectAtIndex:i]]){
//here write wat u need to do
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-07 10:02:52
Mała odmiana 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':
-(IBAction) buttonAction:(id)sender;
{
id parent1 = [sender superview]; // UiTableViewCellContentView
id parent2 = [parent1 superview]; // custom cell containing the content view
id parent3 = [parent2 superview]; // UITableView containing the cell
id parent4 = [parent3 superview]; // UIView containing the table
UIView *myContentView = (UIView *)parent1;
UITableViewCell *myTableCell = (UITableViewCell *)parent2;
UITableView *myTable = (UITableView *)parent3;
UIView *mainView = (UIView *)parent4;
CGRect footerViewRect = myTableCell.frame;
CGRect rect3 = [myTable convertRect:footerViewRect toView:mainView];
[cc doSomethingOnScreenAtY:rect3.origin.y];
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-09 16:53:42
Zawsze używam tagów.
Musisz podklasować UITableviewCell
i obsługiwać naciśnięcie przycisku stamtąd.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-01 05:01:31
To proste; zrób niestandardową komórkę i weź wylot przycisku
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
customCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
cell.yourButton.tag = indexPath.Row;
- (void)buttonPressedAction:(id)sender
Zmień id w powyższej metodzie na (UIButton *)
Możesz uzyskać wartość tego, który przycisk jest stukany, wykonując nadawcę.tag.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-01 05:02:10
Podklasuj przycisk do przechowywania wymaganej wartości, może Utwórz protokół (ControlWithData lub coś takiego). Ustaw wartość po dodaniu przycisku do komórki widoku tabeli. W zdarzeniu touch up sprawdź, czy nadawca przestrzega protokołu i wyodrębnij dane. Zwykle przechowuję odniesienie do rzeczywistego obiektu, który jest renderowany w komórce widoku tabeli.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-06 02:59:31
SWIFT 2 UPDATE
Oto jak dowiedzieć się, który przycisk został naciśnięty + wyślij dane do innego Viewcontrollera z tego przycisku indexPath.row
jak zakładam, że to jest punkt dla większości!
@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")
}
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 niej dostęp.
Oto kod do przekazywania danych do innego VC po naciśnięciu tego przycisku i przejściu komórka indexPath.row
@IBAction func moreInfo(sender: AnyObject) {
let yourOtherVC = self.storyboard!.instantiateViewControllerWithIdentifier("yourOtherVC") as! YourOtherVCVIewController
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("Button tapped")
yourOtherVC.yourVarName = [self.otherVCVariable[indexPath!.row]]
self.presentViewController(yourNewVC, animated: true, completion: nil)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-07 10:21:55
Uwaga tutaj używam niestandardowej komórki ten kod działa dla mnie doskonale
@IBAction func call(sender: UIButton)
{
var contentView = sender.superview;
var cell = contentView?.superview as EmployeeListCustomCell
if (!(cell.isKindOfClass(EmployeeListCustomCell)))
{
cell = (contentView?.superview)?.superview as EmployeeListCustomCell
}
let phone = cell.lblDescriptionText.text!
//let phone = detailObject!.mobile!
let url:NSURL = NSURL(string:"tel://"+phone)!;
UIApplication.sharedApplication().openURL(url);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-18 19:36:01
Rozwiązanie Chrisa Schwerdta, ale potem w Swifcie zadziałało dla mnie:
@IBAction func rateButtonTapped(sender: UIButton) {
let buttonPosition : CGPoint = sender.convertPoint(CGPointZero, toView: self.ratingTableView)
let indexPath : NSIndexPath = self.ratingTableView.indexPathForRowAtPoint(buttonPosition)!
print(sender.tag)
print(indexPath.row)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-17 12:10:18
Ten problem składa się z dwóch części:
1) uzyskanie ścieżki indeksu UITableViewCell
, która zawiera wciśnięty UIButton
Są takie propozycje jak:
Aktualizacja
UIButton
'Stag
w metodziecellForRowAtIndexPath:
z wykorzystaniem wartościrow
ścieżki indeksu. Nie jest to dobre rozwiązanie, ponieważ wymaga ciągłej aktualizacjitag
i nie działa z widokami tabeli z więcej niż jedną sekcją.Dodawanie właściwości
NSIndexPath
do niestandardowej komórki i aktualizowanie jej zamiastUIButton
'Stag
w metodziecellForRowAtIndexPath:
. Rozwiązuje to problem z wieloma sekcjami, ale nadal nie jest dobry, ponieważ wymaga aktualizacji zawsze.Zachowując słabą refencję do rodzica
UITableView
w komórce niestandardowej podczas jej tworzenia i używając metodyindexPathForCell:
, aby uzyskać ścieżkę indeksu. Wydaje się trochę lepiej, nie ma potrzeby aktualizowania czegokolwiek w metodziecellForRowAtIndexPath:
, ale nadal wymaga ustawienia słabego odniesienia podczas tworzenia niestandardowej komórki.Korzystanie z właściwości
superView
komórki, aby uzyskać odniesienie do rodzicaUITableView
. Nie ma potrzeby dodawania żadnych właściwości do niestandardowej komórki i nie ma potrzeby ustawiania / aktualizowania czegokolwiek podczas tworzenia/później. Ale cell ' ssuperView
zależy od szczegółów implementacji iOS. Więc nie można go używać bezpośrednio.
Ale można to osiągnąć za pomocą prostej pętli, ponieważ jesteśmy pewni, że dana komórka musi być w widoku UITableView:
UIView* view = self;
while (view && ![view isKindOfClass:UITableView.class])
view = view.superview;
UITableView* parentTableView = (UITableView*)view;
Więc te sugestie mogą być połączone w prostą i bezpieczną metodę niestandardowych komórek do uzyskania ścieżki indeksu:
- (NSIndexPath *)indexPath
{
UIView* view = self;
while (view && ![view isKindOfClass:UITableView.class])
view = view.superview;
return [(UITableView*)view indexPathForCell:self];
}
Od teraz, ta metoda może być użyta do wykrycia, które {[3] } jest naciśnięte.
2) informowanie innych stron o zdarzeniu naciśnij przycisk
Po wewnętrznej informacji, która UIButton
jest wciśnięta w której komórce z dokładną ścieżką indeksu, informacja ta musi zostać wysłana do innych stron(najprawdopodobniej kontroler widoku obsługujący UITableView
). Tak więc to zdarzenie kliknięcia przycisku może być obsługiwane na podobnym poziomie abstrakcji i logiki jak metoda didSelectRowAtIndexPath:
delegata UITableView.
Dwa można w tym celu zastosować podejścia:
A) delegacja: komórka niestandardowa może mieć właściwość delegate
i może definiować protokół. Po naciśnięciu przycisku po prostu wykonuje metody delegata na swojej właściwości delegate
. Ale ta właściwość delegate
musi być ustawiona dla każdej komórki niestandardowej podczas ich tworzenia. Jako alternatywę, komórka niestandardowa może również wykonywać swoje metody delegowania w widoku tabeli nadrzędnej delegate
.
B) Centrum powiadomień: własne komórki mogą definiować niestandardowa nazwa powiadomienia i zamieść to powiadomienie ze ścieżką indeksu i informacjami widoku tabeli nadrzędnej dostępnymi w obiekcie userInfo
. Nie trzeba niczego ustawiać dla każdej komórki, wystarczy dodać obserwatora dla powiadomienia niestandardowej komórki.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-27 05:19:55
Używam rozwiązania, które podklasa UIButton
i pomyślałem, że powinienem podzielić się nim tutaj, kody w Swift:
class ButtonWithIndexPath : UIButton {
var indexPath:IndexPath?
}
Następnie pamiętaj, aby zaktualizować to indexPath w cellForRow(at:)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let returnCell = tableView.dequeueReusableCell(withIdentifier: "cellWithButton", for: indexPath) as! cellWithButton
...
returnCell.button.indexPath = IndexPath
returnCell.button.addTarget(self, action:#selector(cellButtonPressed(_:)), for: .touchUpInside)
return returnCell
}
Więc odpowiadając na zdarzenie przycisku możesz go używać tak jak
func cellButtonPressed(_ sender:UIButton) {
if sender is ButtonWithIndexPath {
let button = sender as! ButtonWithIndexPath
print(button.indexPath)
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-24 10:21:30
Z Swift 4.2 i iOS 12, UITableView
posiada metodę o nazwie indexPathForRow(at:)
. indexPathForRow(at:)
ma następującą deklarację:
func indexPathForRow(at point: CGPoint) -> IndexPath?
Zwraca ścieżkę indeksu identyfikującą wiersz i sekcję w podanym punkcie.
Poniższy kompletny kod pokazuje, jak zaimplementować indexPathForRow(at:)
, Aby uzyskać odpowiednie IndexPath
z UIButton
znajdującego się w UITableViewCell
:
import UIKit
class CustomCell: UITableViewCell {
let button = UIButton(type: .system)
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
button.setTitle("Tap", for: .normal)
contentView.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
button.topAnchor.constraintEqualToSystemSpacingBelow(contentView.topAnchor, multiplier: 1).isActive = true
button.leadingAnchor.constraintGreaterThanOrEqualToSystemSpacingAfter(contentView.leadingAnchor, multiplier: 1).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
import UIKit
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(CustomCell.self, forCellReuseIdentifier: "Cell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
cell.button.addTarget(self, action: #selector(printIndexPath), for: .touchUpInside)
return cell
}
@objc func printIndexPath(_ sender: UIButton) {
let point = sender.convert(CGPoint.zero, to: tableView)
guard let indexPath = tableView.indexPathForRow(at: point) else { return }
print(indexPath)
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-07 21:46:33