簡體   English   中英

自定義UITableViewCell按鈕動作?

[英]Custom UITableViewCell button action?

我一直在尋找解決方案,但似乎找不到適合我的解決方案。 我有一個內置按鈕的自定義單元格。 我的問題是如何將indexPath傳遞給action方法?

現在我正在做

 [cell.showRewards addTarget:self action:@selector(myAction:) forControlEvents:UIControlEventTouchUpInside];

在我的cellForRowAtIndexPath方法中,我的方法是:

-(IBAction)myAction:(id)sender{
NSIndexPath *indexPath = [self.tableView indexPathForCell:(MyCustomCell *)[sender superview]];
NSLog(@"Selected row is: %d",indexPath.row);
}

有小費嗎? 謝謝。

只想添加我認為最好的解決方案:UIView上的一個類別。

這很簡單:

- (void)somethingHappened:(id)sender
{
    NSIndexPath *indexPath = [self.tableView indexPathForCell:[sender parentCell]];

    // Your code here...
}

只需在UIView上使用此類別:

@interface UIView (ParentCell)

- (UITableViewCell *)parentCell;

@end

@implementation UIView (ParentCell)

- (UITableViewCell *)parentCell
{
    UIView *superview = self.superview;
    while( superview != nil ) {
        if( [superview isKindOfClass:[UITableViewCell class]] )
            return (UITableViewCell *)superview;

        superview = superview.superview;
    }

    return nil;
}

@end
cell.showRewards.tag = indexPath.row;

-(IBAction)myAction:(id)sender
{
UIButton *btn = (UIButton *)sender;
int indexrow = btn.tag;
NSLog(@"Selected row is: %d",indexrow);
}

雖然我覺得為按鈕設置tag是一種方法。 您可能需要編寫代碼以確保每次重用單元格時,都會在按鈕對象上更新相應的標記。

相反,我覺得這可行。 試試這個 -

-(IBAction)myAction:(id)sender
{
CGPoint location            = [sender locationInView:self.tableView];
NSIndexPath *indexPath      = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *swipeCell  = [self.tableView cellForRowAtIndexPath:indexPath];

NSLog(@"Selected row: %d", indexPath.row);
//......
}

基本上你正在做的是獲取相對於tableView的點擊發生位置的坐標。 獲取坐標后, tableView可以使用方法indexPathForRowAtPoint:為您提供indexPathForRowAtPoint: 你很高興去追尋......

瞧,你不僅有indexPath ,還有點擊發生的實際單元格。 要從數據源獲取實際數據(假設其NSArray),您可以 -

[datasource objectAtIndex:[indexPath row]];

試試這個吧。

cell.showRewards.tag=indextPath.row

在cellforrowatindexpath tableview的方法中實現它。

-(IBAction)myAction:(id)sender{
UIButton* btn=(UIButton*)sender;
NSLog(@"Selected row is: %d",btn.tag);
}

您設置按鈕標記值= indexpath並在函數中檢查它,如果標記值是這樣做你想要的

您可以將indexpath分配給按鈕標記,並在方法中進行訪問

cell.showRewards.tag = indexPath.row;

-(IBAction)myAction:(id)sender
{
     NSIndexPath *indexPath = [self.tableView indexPathForCell:[sender tag]];
     NSLog(@"Selected row is: %d",indexPath.row);
}

在自定義UITableViewCell類中:

[self.contentView addSubview:but_you]; 

cellForRowAtIndexPath方法中,您可以編寫:

[cell.showRewards addTarget:self action:@selector(myAction:) forControlEvents:UIControlEventTouchUpInside];    
cell.showRewards.tag = indexPath.row;

我覺得不可思議的是,沒有真正合適的解決方案。

無論出於何種原因,我發現標記方法和'使用屏幕上單元格的可視位置來識別正確的模型對象'在其他答案中概述有點臟。

以下是該問題的兩種不同方法:

子類化UITableViewCell

我使用的解決方案是子類UITableViewCell

@interface MyCustomCell : UITableViewCell

@property (nonatomic, strong) Model *myModelObject;

@end

cellForRowAtIndexPath:創建單元格時cellForRowAtIndexPath:您可能正在使用模型對象來填充單元格數據。 在此方法中,您可以將模型對象分配給單元格。

然后在按鈕點擊處理程序中:

MatchTile *cell = (MatchTile *) sender.superview.superview;

if (cell && cell.myModelObject)
{
    //Use cell.myModelObject
}

說實話,我對這個解決方案並不是百分之百滿意。 將域對象附加到這樣一個專門的UIKit組件感覺就像是不好的做法。

使用Objective-C關聯對象

如果您不想對單元格進行子類化,則可以使用另一些技巧將模型對象與單元格關聯並稍后檢索它。

要從單元格中檢索模型對象,您需要一個唯一的鍵來標識它。 像這樣定義一個:

static char* OBJECT_KEY = "uniqueRetrievalKey"; 

在使用模型對象填充單元格時, cellForRowAtIndexPath:下行添加到cellForRowAtIndexPath:方法。 這會將模型對象與單元格對象相關聯。

objc_setAssociatedObject(cell, OBJECT_KEY, myModelObject, OBJC_ASSOCIATION_RETAIN);

然后,只要您有對該單元格的引用,就可以使用以下方法檢索模型對象:

MyModelObject *myModelObject = (MyModelObject *) objc_getAssociatedObject(cell, OBJECT_KEY);

在反思中,雖然我選擇了第一個(因為我已經將子類化為子類),但第二個解決方案可能更清晰,因為它仍然是ViewController的附加和檢索模型對象的責任。 UITableViewCell不需要了解它。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法寫下面的代碼:

  [cell.zoomButton addTarget:self action:@selector(navigateAction:) forControlEvents:UIControlEventTouchUpInside];
cell.zoomButton.tag=indexPath.row;

然后寫一個這樣的方法:

-(IBAction)navigateAction:(id)sender
{
UIButton *btn = (UIButton *)sender;
int indexrow = btn.tag;
NSLog(@"Selected row is: %d",indexrow);

currentBook = [[bookListParser bookListArray] objectAtIndex:indexrow];

KitapDetayViewController *kitapDetayViewController;
if(IS_IPHONE_5)
{
    kitapDetayViewController = [[KitapDetayViewController alloc] initWithNibName:@"KitapDetayViewController" bundle:Nil];
}

else
{
    kitapDetayViewController = [[KitapDetayViewController alloc] initWithNibName:@"KitapDetayViewController_iPhone4" bundle:Nil];
}
kitapDetayViewController.detailImageUrl = currentBook.detailImageUrl;
kitapDetayViewController.bookAuthor = currentBook.bookAuthor;
kitapDetayViewController.bookName = currentBook.bookName;
kitapDetayViewController.bookDescription = currentBook.bookDescription;
kitapDetayViewController.bookNarrator=currentBook.bookNarrator;
kitapDetayViewController.bookOrderHistory=currentBook.bookOrderDate;
int byte=[currentBook.bookSizeAtByte intValue];
int mb=byte/(1024*1024);
NSString *mbString = [NSString stringWithFormat:@"%d", mb];
kitapDetayViewController.bookSize=mbString;
kitapDetayViewController.bookOrderPrice=currentBook.priceAsText;
kitapDetayViewController.bookDuration=currentBook.bookDuration;
kitapDetayViewController.chapterNameListArray=self.chapterNameListArray;
// [[bookListParser bookListArray ]release];
[self.navigationController pushViewController:kitapDetayViewController animated:YES];
}

如果你想要按鈕的indexPath 檢測在UITableView按下了哪個UIButton描述了如何。

基本上按鈕動作變為:

 - (void)checkButtonTapped:(id)sender
    {
        CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
        NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
        if (indexPath != nil)
        {
         ...
        }
    }

[sender superview]您不訪問MyCustomCell ,但它是contentView 閱讀UITableViewCell類參考:

contentView返回單元格對象的內容視圖。 (只讀)

@property(nonatomic, readonly, retain) UIView *contentView

討論: UITableViewCell對象的內容視圖是單元格顯示的內容的默認超級視圖。 如果要通過簡單地添加其他視圖來自定義單元格,則應將它們添加到內容視圖中,以便在單元格進入和退出編輯模式時將它們正確定位。

修改代碼的最簡單方法是使用[[sender superview] superview] 但是如果稍后修改單元格並在另一個視圖中插入按鈕,這將停止工作。 contentView出現在iPhoneOS 2.0 類似的未來修改將影響您的代碼。 這就是我不建議用這種方式的原因。

這是“最簡單的方法”(在IOS11上測試):

NSIndexPath *indexPath = [myTable indexPathForRowAtPoint:[[[sender superview] superview] center]];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM