ios 附件ButtonTappedForRowWithIndexPath:没有被调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12296904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:00:53  来源:igfitidea点击:

accessoryButtonTappedForRowWithIndexPath: not getting called

iosobjective-cuitableviewaccessoryview

提问by jimbob

I am creating a Detail disclosure button which is getting populated using an array.... However the accessoryButtonTappedForRowWithIndexPath: function is not being called in my class. It is a TableviewDelegateand TableviewDatasourcedelegate.

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

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

The NSLog isnt printing to console which leads me to believe the function isnt being called... This is of course when I select on a cell. A screenshot below shows how I have my cell setup.

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

enter image description here

在此处输入图片说明

采纳答案by Coder

Did you just click on the cell to select it or did you actually click on the accessory button indicator on the cell? It isn't clear from your question.

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

accessoryButtonTappedForRowWithIndexPathis applicable when you click on the button icon within the cell and not when you select the cell.

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

回答by Tom

The doc says that the method tableView:accessoryButtonTappedForRowWithIndexPath:is not called when an accessory view is set for the row at indexPath. The method is only called when the accessoryViewproperty is niland when one uses and set the accessoryTypeproperty to display a built-in accessory view.

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

As I understand it, accessoryViewand accessoryTypeare mutually exclusive. When using accessoryType, the system will call tableView:accessoryButtonTappedForRowWithIndexPath:as expected, but you have to handle the other case by yourself.

根据我的理解,accessoryViewaccessoryType相互排斥。使用时accessoryType,系统会tableView:accessoryButtonTappedForRowWithIndexPath:按预期调用,但其他情况您必须自己处理。

The way Apple does this is shown in the Accessorysample project of the SDK. In the cellForRowAtIndexPathmethod of the dataSource delegate, they set a target/action to a custom accessory button. Since one can't pass the indexPathto the action, they call an auxiliary method to retrieve the corresponding indexPathand they pass the result to the delegate method:

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];
    }
}

For some reason, your setup seems to fall in the accessoryView case. Have you tried to set the accessoryTypewith code instead of using the Interface Builder ?

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

回答by mdebeus

This seems very relevant...

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

Disclosure indicator: When this element is present, users know they can tap anywhere in the row to see the next level in the hierarchy or the choices associated with the list item. Use a disclosure indicator in a row when selecting the row results in the display of another list. Don't use a disclosure indicator to reveal detailed information about the list item; instead, use a detail disclosure button for this purpose.

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

Detail disclosure button: Users tap this element to see detailed information about the list item. (Note that you can use this element in views other than table views, to reveal additional details about something; see “Detail Disclosure Buttons” for more information.) In a table view, use a detail disclosure button in a row to display details about the list item. Note that the detail disclosure button, unlike the disclosure indicator, can perform an action that is separate from the selection of the row. For example, in Phone Favorites, tapping the row initiates a call to the contact; tapping the detail disclosure button in the row reveals more information about the contact.

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

回答by Keith Coughtrey

Converting the top answer to Swift 3:

将最佳答案转换为 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)
    }
}

回答by Avt

According to UITableViewCellAccessoryType's documentation it is expected behaviour:

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

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

Constants UITableViewCellAccessoryNone The cell does not have any accessory view. This is the default value.

UITableViewCellAccessoryDisclosureIndicator The cell has an accessory control shaped like a chevron. This control indicates that tapping the cell triggers a push action. The control does not tracktouches.

UITableViewCellAccessoryDetailDisclosureButton The cell has an info button and a chevron image as content. This control indicates that tapping the cell allows the user to configure the cell's contents. The control trackstouches.

UITableViewCellAccessoryCheckmark The cell has a check mark on its right side. This control does not tracktouches. The delegate of the table view can manage check marks in a section of rows (possibly limiting the check mark to one row of the section) in its tableView:didSelectRowAtIndexPath: method.

UITableViewCellAccessoryDetailButton The cell has an info button without a chevron. This control indicates that tapping the cell displays additional information about the cell's contents. The control trackstouches.

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

UITableViewCellAccessoryDisclosureIndicator 单元格有一个像 V 形的辅助控件。此控件指示点击单元格会触发推送操作。该控件不跟踪触摸。

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

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

UITableViewCellAccessoryDe​​tailButton 单元格有一个没有人字形的信息按钮。此控件表示点击单元格会显示有关单元格内容的附加信息。控件 跟踪触摸。

回答by wm_j_ray

drew is spot on.

画的是现场。

If you change to 'DetailDisclosure' in Storyboard, then the method will fire. (xCode 4.6 DP3)

如果换在故事板“DetailDisclosure”,则该方法将火。(xCode 4.6 DP3)

回答by nishant

This is another way to handle the disclosure button using the storyboard. You should click the table view cell and goto the Connections Inspector. There is a section called Triggered Segues, and you can drag from the selection line to the UIViewController that you want to segue to. The segue will happen automatically and you can capture prepareForSegue to capture the notification when it does.
The function accessoryButtonTappedForRowWithIndexPath never gets called for the disclosure button. It only gets called for the detailed disclosure button.

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

回答by Lewis Edward Garrett

My tableView's accessoryButtonTappedForRowWithIndexPath(…)was not being called when the Detail disclosure button was hit. I eventually found that the problem was simply that tableView delegate had not been set:

accessoryButtonTappedForRowWithIndexPath(…)当点击 Detail 公开按钮时,我的 tableView没有被调用。我最终发现问题只是 tableView 委托尚未设置:

self.tableView.delegate = self

self.tableView.delegate = self