35

我正在创建一个使用数组填充的详细信息披露按钮。但是,在我的类中没有调用 accessoryButtonTappedForRowWithIndexPath: 函数。它是一个TableviewDelegateTableviewDatasource委托。

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
    NSLog(@"reaching accessoryButtonTappedForRowWithIndexPath:");
    [self performSegueWithIdentifier:@"modaltodetails" sender:[self.eventsTable cellForRowAtIndexPath:indexPath]];
}

NSLog 没有打印到控制台,这让我相信该函数没有被调用......这当然是当我在单元格上选择时。下面的屏幕截图显示了我如何设置单元格。

在此处输入图像描述

4

8 回答 8

62

该文档说,tableView:accessoryButtonTappedForRowWithIndexPath:当为 at 处的行设置辅助视图时,不会调用该方法indexPath。该方法仅在accessoryView属性为时调用,nil并且在使用并将accessoryType属性设置为显示内置附件视图时调用。

据我了解,accessoryView并且accessoryType是互斥的。使用accessoryType时,系统会tableView:accessoryButtonTappedForRowWithIndexPath:按预期调用,但其他情况需要您自己处理。

Apple 执行此操作的方式显示在AccessorySDK 的示例项目中。在cellForRowAtIndexPathdataSource 委托的方法中,他们将目标/操作设置为自定义附件按钮。由于无法将 传递indexPath给动作,因此他们调用辅助方法来检索相应indexPath的并将结果传递给委托方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    ...

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    ...

    // set the button's target to this table view controller so we can interpret touch events and map that to a NSIndexSet
    [button addTarget:self action:@selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
    ...
    cell.accessoryView = button;

    return cell;
}


- (void)checkButtonTapped:(id)sender event:(id)event{
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
    if (indexPath != nil){
        [self tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath];
    }
}

出于某种原因,您的设置似乎属于附件视图案例。您是否尝试过设置accessoryTypewith 代码而不是使用 Interface Builder ?

于 2012-10-10T01:14:15.813 回答
39

这似乎非常相关......

披露指示器:当此元素存在时,用户知道他们可以点击行中的任意位置以查看层次结构中的下一级或与列表项关联的选项。选择行在另一个列表的显示中,在一行中使用公开指示符。不要使用披露指标来透露有关列表项的详细信息;相反,为此目的使用详细信息披露按钮。

详细信息披露按钮:用户点击此元素可查看有关列表项的详细信息。(请注意,您可以在除表视图之外的视图中使用此元素,以显示有关某些内容的其他详细信息;有关更多信息,请参阅“详细信息披露按钮”。)在表视图中,使用一行中的详细信息披露按钮来显示有关某事的详细信息列表项。请注意,与披露指示器不同,详细信息披露按钮可以执行与选择行分开的操作。例如,在电话收藏夹中,点击该行会向联系人发起呼叫;点击行中的详细信息披露按钮可显示有关联系人的更多信息。

于 2014-01-07T03:20:50.080 回答
11

将最佳答案转换为 Swift 3:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    ...
    let unseletcedImage = UIImage(named: "<imagename>")
    let seletcedImage = UIImage(named: "<imagename>")
    let button = UIButton(type: .custom)
    // match the button's size with the image size
    let frame = CGRect(x: CGFloat(0.0), y: CGFloat(0.0), width: CGFloat((unseletcedImage?.size.width)!), height: CGFloat((unseletcedImage?.size.height)!))
    button.frame = frame
    button.setBackgroundImage(unseletcedImage, for: .normal)
    button.setBackgroundImage(seletcedImage, for: .selected)
    cell?.accessoryView = button
    let action = #selector(checkButtonTapped(sender:event:))
    (cell?.accessoryView as? UIButton)?.addTarget(self, action: action, for: .touchUpInside)
    ....
    return cell!

}

@objc func checkButtonTapped(sender: UIButton?, event: UIEvent) {
    let touches = event.allTouches
    let touch = touches!.first
    guard let touchPosition = touch?.location(in: self.tableView) else {
        return
    }
    if let indexPath = tableView.indexPathForRow(at: touchPosition) {
        tableView(self.tableView, accessoryButtonTappedForRowWith: indexPath)
    }
}
于 2017-03-08T22:23:48.623 回答
9

根据 UITableViewCellAccessoryType 的文档,这是预期的行为:

typedef enum : NSInteger {    
UITableViewCellAccessoryNone,   
UITableViewCellAccessoryDisclosureIndicator,   
UITableViewCellAccessoryDetailDisclosureButton,   
UITableViewCellAccessoryCheckmark,   
UITableViewCellAccessoryDetailButton } UITableViewCellAccessoryType;

常量 UITableViewCellAccessoryNone 该单元格没有任何附件视图。这是默认值。

UITableViewCellAccessoryDisclosureIndicator 该单元格有一个形状像人字形的附件控件。此控件表示点击单元格会触发推送操作。该控件不跟踪触摸。

UITableViewCellAccessoryDe​​tailDisclosureButton 该单元格有一个信息按钮和一个人字形图像作为内容。此控件指示点击单元格允许用户配置单元格的内容。控制轨道触摸。

UITableViewCellAccessoryCheckmark 该单元格的右侧有一个复选标记。此控件不跟踪触摸。表视图的委托可以在其 tableView:didSelectRowAtIndexPath: 方法中管理某一行中的复选标记(可能将复选标记限制为该部分的一行)。

UITableViewCellAccessoryDe​​tailButton 该单元格有一个没有 V 形的信息按钮。此控件表示点击单元格会显示有关单元格内容的附加信息。控制 轨道触摸。

于 2014-07-07T10:02:27.210 回答
7

您是否只是单击单元格以选择它,还是您实际上单击了单元格上的附件按钮指示器?从你的问题看不清楚。

accessoryButtonTappedForRowWithIndexPath当您单击单元格内的按钮图标时适用,而不是当您选择单元格时。

于 2012-09-06T09:57:26.680 回答
2

画的很到位。

如果您在 Storyboard 中更改为“DetailDisclosure”,则该方法将触发。(xCode 4.6 DP3)

于 2012-12-10T20:57:26.723 回答
0

这是使用情节提要处理披露按钮的另一种方法。您应该单击表格视图单元格并转到 Connections Inspector。有一个名为 Triggered Segues 的部分,您可以从选择线拖动到您想要 segue 的 UIViewController。segue 将自动发生,您可以捕获 prepareForSegue 以在它发生时捕获通知。
永远不会为显示按钮调用函数 accessoryButtonTappedForRowWithIndexPath。它只被调用详细的披露按钮。

于 2015-01-25T00:25:53.007 回答
0

当点击详细信息披露按钮时,我的 tableViewaccessoryButtonTappedForRowWithIndexPath(…)没有被调用。我最终发现问题只是没有设置 tableView 委托:

self.tableView.delegate = self

于 2019-09-25T20:54:10.417 回答