Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 调用选择器时识别嵌入在自定义UITableViewCell中的UISegmentedControl_Iphone_Ios_Uitableview_Uisegmentedcontrol - Fatal编程技术网

Iphone 调用选择器时识别嵌入在自定义UITableViewCell中的UISegmentedControl

Iphone 调用选择器时识别嵌入在自定义UITableViewCell中的UISegmentedControl,iphone,ios,uitableview,uisegmentedcontrol,Iphone,Ios,Uitableview,Uisegmentedcontrol,我有一个自定义UITableViewCell,它通过单元格的contentView属性将UISegmentedControl添加为子视图,如下所示: #define TABLECELL_SEGMENT_TAG 1 ... - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UISegmentedControl *testSe

我有一个自定义UITableViewCell,它通过单元格的contentView属性将UISegmentedControl添加为子视图,如下所示:

#define TABLECELL_SEGMENT_TAG 1

...


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

    UISegmentedControl *testSegmentedControl;

    // Check for a reusable cell first, use that if it exists
    UITableViewCell *tableCell = [tableView dequeueReusableCellWithIdentifier:@"OurCustomCell"];

    // If there is no reusable cell of this type, create a new one
    if (!tableCell) {
        tableCell = [[[UITableViewCell alloc] 
                      initWithStyle:UITableViewCellStyleSubtitle
                      reuseIdentifier:@"OurCustomCell"] autorelease];


        // Create our segmented control
        NSArray *segmentItems = [NSArray arrayWithObjects:@"Option 1", @"Option 2", nil];
        UISegmentedControl *testSegmentedControl = [[UISegmentedControl alloc] initWithItems:segmentItems];
        [testSegmentedControl setTag:TABLECELL_SEGMENT_TAG];
        [[tableCell contentView] addSubview:testSegmentedControl];
        [testSegmentedControl release];
    }

    // Set the selected segment status as required
    testSegmentedControl = (UISegmentedControl *)[tableCell.contentView viewWithTag:TABLECELL_SEGMENT_TAG];

    ...

    [testSegmentedControl addTarget:self
                         action:@selector(segmentedControlUpdated:)
               forControlEvents:UIControlEventValueChanged];        

    return tableCell;
}
我需要能够做的是为每个分段控件设置
addTarget
选择器,以便它识别所讨论的行,一个明显的解决方案是使用分段控件的标记。但是,您可以看到,如果通过UITableView的
dequeueReusableCellWithIdentifier:
方法返回现有单元格,则我已经在使用标记从自定义单元格的contentView中检索控件


因此,我只是想知道实现这一目标的最佳方式是什么?(我想我可以简单地扩展UISegmentedControl类来添加一个
associatedTableRow
属性,但我想知道是否有更优雅的解决方案。)

创建一个UITableViewCell的子类,该子类引用UISegmentedControl作为属性,并实例化它而不是UITableViewCell。然后,您不需要标记来引用分段控件,您可以使用它来保存行号


但是,您也可以将行号作为属性放在该子类中,甚至可以让该子类处理目标操作。在任何情况下,创建一个子类都可以让您更灵活地处理此问题。

创建一个UITableViewCell的子类,该子类引用UISegmentedControl作为属性,并实例化该子类而不是UITableViewCell。然后,您不需要标记来引用分段控件,您可以使用它来保存行号


但是,您也可以将行号作为属性放在该子类中,甚至可以让该子类处理目标操作。在任何情况下,创建一个子类都会给你更大的灵活性来处理这个问题。

因为子类化总是我做superview舞蹈时最糟糕的选择

- (IBAction)controlChanged:(UIControl *)sender
    NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
    // do something
}
由于iOS7更改了视图层次结构,上述代码将无法工作。您需要使用
InExpathForRowatPoint:

- (IBAction)controlChanged:(UIControl *)sender {
    CGPoint senderOriginInTableView = [sender convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:senderOriginInTableView];
    // do something
}

因为子类化总是最糟糕的选择,我会跳superview舞

- (IBAction)controlChanged:(UIControl *)sender
    NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
    // do something
}
由于iOS7更改了视图层次结构,上述代码将无法工作。您需要使用
InExpathForRowatPoint:

- (IBAction)controlChanged:(UIControl *)sender {
    CGPoint senderOriginInTableView = [sender convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:senderOriginInTableView];
    // do something
}

+1子类化始终是表视图单元格自定义的选择方法。+1子类化始终是表视图单元格自定义的选择方法。有点离题:为什么不将addTarget调用移到if(!tableCell)语句中?在您的代码中,每次调用CellForRowatingIndexPath时,即每次在屏幕上滚动单元格时,事件都会被连接。@hennes它当前在单元格构造函数if语句之外,因为我认为可能有一种自定义setTarget选择器的方法。也就是说,我将根据答案的建议,根据需要搬回去等。:-)有点离题:为什么不将addTarget调用移到if(!tableCell)语句中?在您的代码中,每次调用CellForRowatingIndexPath时,即每次在屏幕上滚动单元格时,事件都会被连接。@hennes它当前在单元格构造函数if语句之外,因为我认为可能有一种自定义setTarget选择器的方法。也就是说,我将根据答案的建议,根据需要搬回去等。:-)+1一个简洁的解决方案。也就是说,我怀疑对于一个非同寻常的案例(在这个案例中,有相当多的细胞定制正在进行),子分类可能是一个更简洁的解决方案,或者你是否相信呢?在我看到Matthias的答案之前,这是一个不会消失的痛苦。使用触摸检测的传统技术不适用于分段控制,因此这非常有用!好。实际上,这在iOS7上不应该起作用。事实证明,走更高层的道路并不是最好的主意。所以要小心。我用一种应该始终有效的方法更新了答案。+1一个简洁的解决方案。也就是说,我怀疑对于一个非同寻常的案例(在这个案例中,有相当多的细胞定制正在进行),子分类可能是一个更简洁的解决方案,或者你是否相信呢?在我看到Matthias的答案之前,这是一个不会消失的痛苦。使用触摸检测的传统技术不适用于分段控制,因此这非常有用!好。实际上,这在iOS7上不应该起作用。事实证明,走更高层的道路并不是最好的主意。所以要小心。我用一种应该一直有效的方法更新了答案。