如何检索UISwitch的UITableView行号?
我已经尝试了几种方法张贴在这里,但我不能让我的表充满开关返回改变的开关的单元格的索引值。 我正在以编程方式创build包含表的视图(没有xib)。
TableSandboxAppDelegate.m我在didFinishLaunchingWithOptions:
实例化视图控制器didFinishLaunchingWithOptions:
with:
... TableSandboxViewController *sandboxViewController = [[TableSandboxViewController alloc] init]; [[self window] setRootViewController:sandboxViewController]; ...
TableViewController.h文件读取:
@interface TableSandboxViewController : UITableViewController { NSMutableArray *_questionOrder; NSMutableArray *switchStates; } @end
TableViewController.m cellForRowAtIndexPath:
读取:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MainCell"]; UISwitch *theSwitch = nil; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MainCell"]; theSwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; theSwitch.tag = 100; [theSwitch addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged]; [cell.contentView addSubview:theSwitch]; } else { theSwitch = [cell.contentView viewWithTag:100]; } if ([[switchStates objectAtIndex:indexPath.row] isEqualToString:@"ON"]) { theSwitch.on = YES; } else { theSwitch.on = NO; } return cell;
TableViewController.m -(IBAction)switchChanged:(UISwitch *)sender
读取:
UITableViewCell *theParentCell = [[sender superview] superview]; NSIndexPath *indexPathOfSwitch = [self.tableView indexPathForCell:theParentCell]; NSLog(@"Switch changed at index: %d", indexPathOfSwitch.row);
我的日志结果始终是“索引切换:0”。 我觉得问题是在CGPoint行,我已经尝试了“sender”([sender superview],[[sender superview] superview]等replace组合)。 我不觉得这条线是指向显示表的视图。
我究竟做错了什么?
注意10/9,9:15 EDT:我的目标是能够处理大约100个是/否的问题,所以重用是一个关键。 我想滚动并让表格成为每个开关的状态,并且能够在离开视图时检索它们。
标签是一个好的解决scheme,但有点笨拙,因为单元格(因此它们的子视图)不断被重复使用,改变它们的行,因此也是他们需要的标签。
相反,我通常保留其中的一个:
- (NSIndexPath *)indexPathWithSubview:(UIView *)subview { while (![subview isKindOfClass:[UITableViewCell self]] && subview) { subview = subview.superview; } return [self.tableView indexPathForCell:(UITableViewCell *)subview]; }
那么当我得到一个IBAction:
- (IBAction)someSubviewAction:(id)sender { NSIndexPath *indexPath = [self indexPathWithSubview:(UIView *)sender]; // carry on from here }
您可以将切换视图标记设置为行索引。 而不是theSwitch.tag = 100;
做
-(UITableViewCell*)tableView:table cellForRowAtIndexPath:indexPth { UISwitch *theSwitch = nil; if (cell == nil) { ... // as per your example [cell.contentView addSubview:theSwitch]; } else { theSwitch = subviewWithClass(cell.contentView, [UISwitch class]); } theSwitch.tag = indexPath.row; ... }
添加这个辅助函数来replaceviewWithTag:
call
UIView *subviewWithClass(UIView *contentview, Class klass) { for (UIView *view in contentview.subviews) if ([view isKindOfClass:klass]) return view; return nil; }
然后在你的switchChanged函数中检索标签,这是一个行索引
-(IBAction)switchChanged:(UISwitch *)sender { NSLog(@"Selected Switch - %d", sender.tag); ... }
如果你使用基于块的(如https://github.com/brightsoftdev/iOS-Block-Based-Bindings/blob/master/UISwitch%2BBindings.m ),你不需要担心获得行,因为您可以引用传入tableView:cellForRowAtIndexPath:的块中的indexPath。
和@danh类似,我使用了多次使用的扩展来提出这个解决scheme。
@interface UIView (Find) - (id)findSuperviewOfClass:(Class)class; - (NSIndexPath *)findIndexPath; @end @implementation UIView (Find) - (id)findSuperviewOfClass:(Class)class { return [self isKindOfClass:class] ? self : [self.superview findSuperviewOfClass:class]; } - (NSIndexPath *)findIndexPath { UITableView *tableView = [self findSuperviewOfClass:[UITableView class]]; return [tableView indexPathForCell:[self findSuperviewOfClass:[UITableViewCell class]]]; } @end
对于iOS6 +,您可以维护一个NSMutableArray queuedSwitches
在-tableView:cellForrowAtIndexPath:
如果不是空的,你将会得到一个开关,并把它放在自定义单元格中,并将它分配给一个属性。 如果为空,则创build一个新的。
在-tableView:didEndDisplayingCell:forRowAtIndexPath:
你将它添加到quededSwitches
并将其从它的单元格中删除。
这将只为可见单元分配足够的开关并重新使用它们。
开关全部接线到一个动作。
-(void)switchAction:(UISwitch *)switch { NSIndexPath *indexPath = [self.tableView indexPathForCell:[switch superView]]; //… }
你可以创build一个UISwitch的子类并添加一个indexPath属性,然后在cellForRowAtIndexPath中设置indexPath:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { SwitchCell *returnCell = [tableView dequeueReusableCellWithIdentifier:@"SwitchCell" forIndexPath:indexPath]; returnCell.switch.indexPath = indexPath; return returnCell; }