如何知道UITableview行号
我有一个UITableViewCell
与UISwitch
作为每个单元的附件。 当我改变单元格中的开关值时,怎样才能知道开关在哪一行? 我需要切换值更改事件中的行号。
标签,子类或视图层次结构导航功能太多了! 。 在你的行动方法中做到这一点:
CGPoint hitPoint = [sender convertPoint:CGPointZero toView:self.tableView]; NSIndexPath *hitIndex = [self.tableView indexPathForRowAtPoint:hitPoint];
可以使用任何类型的视图,多节表格,只要发件人的原点在单元格框架内(感谢rob!),通常就是这样。
这里是在UITableView Swift扩展中:
extension UITableView { func indexPath(for view: UIView) -> IndexPath? { let location = view.convert(CGPoint.zero, to: self) return self.indexPathForRow(at: location) } }
如果将tag
属性设置为行号(如其他答案所建议的那样),则必须在tableView:cellForRowAtIndexPath:
每个单元格可以重复使用不同的行)中更新它。
相反,当你需要行号时,你可以从UISwitch
(或任何其他视图)到UITableViewCell
,然后到UITableView
,并向表视图索引单元的索引路径。
static NSIndexPath *indexPathForView(UIView *view) { while (view && ![view isKindOfClass:[UITableViewCell class]]) view = view.superview; if (!view) return nil; UITableViewCell *cell = (UITableViewCell *)view; while (view && ![view isKindOfClass:[UITableView class]]) view = view.superview; if (!view) return nil; UITableView *tableView = (UITableView *)view; return [tableView indexPathForCell:cell]; }
这在tableView:cellForRowAtIndexPath:
不需要任何东西。
在cellForRowAtIndexPath:
,将控件的tag
属性设置为indexPath.row
我更喜欢使用子视图,如果你知道你的布局,它通常是超级简单,1行短…
NSIndexPath *indexPath = [tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
就是说,如果它嵌套更多,则会添加更多的高级视图。
位更多信息:
所有你正在做的是要求父视图和它的父视图这是单元格。 然后你问你的tableview你刚得到的那个单元格的indexpath。
接受的解决方案是一个聪明的黑客。
然而,为什么我们需要使用生命值,如果我们可以利用UIView上已经可用的tag
属性? 你会说, 标签可以只存储行或部分,因为它是一个单一的Int 。
那么…不要忘记你的根源家伙(CS101)。 一个Int可以存储两个两倍大小的整数。 这是这个扩展:
extension Int { public init(indexPath: IndexPath) { var marshalledInt: UInt32 = 0xffffffff let rowPiece = UInt16(indexPath.row) let sectionPiece = UInt16(indexPath.section) marshalledInt = marshalledInt & (UInt32(rowPiece) << 16) marshalledInt = marshalledInt + UInt32(sectionPiece) self.init(bitPattern: UInt(marshalledInt)) } var indexPathRepresentation: IndexPath { let section = self & 0x0000ffff let pattern: UInt32 = 0xffff0000 let row = (UInt32(self) & pattern) >> 16 return IndexPath(row: Int(row), section: Int(section)) } }
在你的tableView(_:, cellForRowAt:)
你可以:
cell.yourSwitch.tag = Int(indexPath: indexPath)
然后在动作处理程序中,您可以:
func didToogle(sender: UISwitch){ print(sender.tag.indexPathRepresentation) }
但是请注意这是限制: 行和部分不得大于65535. (UInt16.max)
我怀疑你的tableView的索引会走高,但如果他们这样做,挑战自己,实现更有效的包装方案。 假如我们有一个很小的部分,我们不需要全部16位代表一个部分。 我们可以有我们的int布局,如:
{section area length}{all remaining}[4 BITS: section area length - 1]
也就是说我们的4个LSB表示分区的长度 – 1,因为我们至少为一个分区分配了1个比特。 因此,如果我们的部分是0,那么这个行可以占用多达27位([1] [27] [4]),这肯定应该足够了。
一个常见的方法是将控件的tag
(在你的情况下是开关)设置为可以用来标识行或表示对象的东西。
例如,在tableView:cellForRowAtIndexPath:
将交换机的tag
属性设置为indexPath.row
并在您的操作方法中,您可以从发件人获取标签。
就个人而言,我不喜欢这种方法,更喜欢UITableViewCell的子类。 另外,向标签添加一个“偏移量”可能是一个好主意,以防止与其他视图的标签发生冲突。
一位同事建议如下,我把它做成了一个UITableView类:
+(UITableViewCell*)findParentCellForSubview:(UIView*)view { while (([view isKindOfClass:[UITableViewCell class]] == NO) && ([view superview] != nil)) view = [view superview]; if ([view superview] != nil) return (UITableViewCell*)view; return nil; }
仍然黑 – 但它的作品。
使用superView的更多变体。 像UIView类别工作。
- (UITableViewCell *)superCell { if (!self.superview) { return nil; } if ([self.superview isKindOfClass:[UITableViewCell class]]) { return (UITableViewCell *)self.superview; } return [self.superview superCell]; }
我不知道多个部分,但我可以给你一个部分…
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSInteger index=indexPath.row; NSString *string=[[NSString alloc]initWithFormat:@"%ld",(long)index]; }
从这里你可以得到行号,你可以把它保存到字符串….
这个帖子接受的答案是非常好的。 我想建议读者,在这篇文章中从@robmayoff派生的以下内容也完全正确:
- (NSIndexPath *)indexPathForView:(UIView *)view inTableView:(UITableView *)tableView { while (view && ![view isKindOfClass:[UITableViewCell class]]) view = view.superview; UITableViewCell *cell = (UITableViewCell *)view; return [tableView indexPathForCell:cell]; }
有些人认为这种方法由于while循环而包含了太多的计算工作。 另一种方法是将视图的原点转换为表视图坐标空间并调用indexPathForRowAtPoint:
隐藏更多的工作。
有些人认为,这种方法相对于潜在的SDK更改是不安全的。 事实上,苹果公司已经改变了一次tableview单元格层次,添加一个contentView
到单元格。 这种方法在这种变化之前和之后都有效。 只要查看祖先可以通过一系列的超级查看(这与UIKit中的任何东西一样重要),这是很好的代码。