【问题标题】:UISwitch inside custom UITableViewCell not available自定义 UITableViewCell 中的 UISwitch 不可用
【发布时间】:2010-11-22 07:20:53
【问题描述】:

我在自定义 UITableViewCell(我称之为 RootLabeledSwitchTableCell 的子类)中有一个 UISwitch

该单元格包含一个 UILabelUISwitch 并排在一起。

我有一个名为keychainSwitch@property 指向此自定义单元格内的开关:

@interface RootLabeledSwitchTableCell : UITableViewCell {
    IBOutlet UILabel *textLabel;
    IBOutlet UISwitch *labeledSwitch;
}

@property (nonatomic, retain) IBOutlet UILabel *textLabel;
@property (nonatomic, retain) IBOutlet UISwitch *labeledSwitch;

@end

在我的表格视图委托中,我添加了一个选择器,如果切换状态被翻转,则调用该选择器:

- (UITableViewCell *) tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   NSString *CellIdentifier = [NSString stringWithFormat: @"%d:%d", [indexPath indexAtPosition:0], [indexPath indexAtPosition:1]];
   UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
   if (cell == nil) {
       switch (indexPath.section) {
       case(kMyFirstSection): {
           switch (indexPath.row) {
               case(kMyFirstSectionFirstRow) {
                   [cellOwner loadMyNibFile:@"RootLabeledSwitchTableCell"];
                   cell = (RootLabeledSwitchTableCell *)cellOwner.cell;
                   self.keychainSwitch = [(RootLabeledSwitchTableCell *)cell labeledSwitch];
                   [self.keychainSwitch addTarget:self action:@selector(keychainOptionSwitched) forControlEvents:UIControlEventValueChanged];
                   break;
               }
               // ...
           }
       }
       // ...
   }
}

所以这个选择器可以正常工作:

- (void) keychainOptionSwitched {
   NSLog(@"Switched keychain option from %d to %d", ![self.keychainSwitch isOn], [self.keychainSwitch isOn]);
}

但是,我不能使用UISwitch 实例的-setOn:animated: 方法来初始化其初始状态:

- (void) updateInterfaceState {
   BOOL isFirstTimeRun = [[[NSUserDefaults standardUserDefaults] objectForKey:kIsFirstTimeRunKey] boolValue];
   if (isFirstTimeRun) {
      [self.keychainSwitch setOn:NO animated:NO];
   }
}

通过测试,self.keychainSwitchnil 导致 -setOn:animated 什么也不做,但我仍然可以操作开关,NSLog 语句将正确打印开关状态更改,例如:

[Session started at 2009-08-24 07:04:56 -0700.]
2009-08-24 07:04:58.489 MyApp[29868:20b] keychain switch is: nil
2009-08-24 07:05:00.641 MyApp[29868:20b] Switched keychain option from 1 to 0
2009-08-24 07:05:01.536 MyApp[29868:20b] Switched keychain option from 0 to 1
2009-08-24 07:05:02.928 MyApp[29868:20b] Switched keychain option from 1 to 0

UITableView 委托方法中设置 self.keychainSwitch 有什么遗漏吗?

【问题讨论】:

    标签: iphone properties uitableview uiswitch


    【解决方案1】:

    我认为这里发生的事情是您试图在单元格不在视线范围内时调用该操作,所以发生的情况是单元格当时已卸载,因此您一次获得钥匙串开关的 nil它进入视野,然后它不再是零,因为它重新加载。但是我看到您正在像这样分配开关

     self.keychainSwitch = [(RootLabeledSwitchTableCell *)cell labeledSwitch];
    

    它是对表格单元格中开关的引用,而您没有保留它,因此它使开关变为 nil ,因为当单元格消失时被卸载并且 keychainSwitch 结果变为 nil 并且因此,您的班级成员也变为零。您可能希望保留 keychainSwitch,然后在重建表单元时将开关从 keychainSwitch 或类似的东西中取出。希望这会有所帮助

    【讨论】:

    • self.keychainSwitch = [[(RootLabeledSwitchTableCell *)cell 标签开关] 保留];不起作用。
    • 另外,您可能仍然保留了财产...当您尝试上述行时会发生什么?
    • 此外,当我调用 -updateInterfaceState 方法时,所有表格视图单元格都在视图中,包括带有 keychainSwitch 实例的单元格。
    • 我确实在属性定义中指定(非原子,保留)。应用程序在任何一种情况下都不会崩溃:self.keychainSwitch 只是 nil。
    • 我认为的问题仍然是单元格的出队,如果不查看更多代码,很难找到一个好的解决方案,但也许可以尝试将您的开关(或开关值)保存在一个数组中您的 viewController 并且当您要求重新加载单元格时,您可以从那里获取其值(或设置其切换视图)。由于您只使用一个出列标识符,因此您的单元格不会保留开关的状态,因此无论如何您每次重新加载单元格时都必须重置它(如果这是您想要的行为)
    【解决方案2】:

    我花了很长时间摆弄带有简单标签的自定义 UITableViewCells 并打开它,然后才发现我可以添加一个 UISwitch 作为附件视图。无论如何,您可能已经意识到这一点,并且出于其他原因想要自定义单元格,但以防万一我想提一下!

    您按如下方式执行此操作(在 -tableView:cellForRowAtIndexPath 方法中):

    UISwitch *mySwitch = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
    cell.accessoryView = mySwitch;
    

    accessoryView 位还负责调整大小和定位,因此我们可以使用 CGRectZero。

    然后您就可以按如下方式使用系统控制事件和 setOn 方法(注意我们将其转换为我们知道的 UISwitch 指针):

    [(UISwitch *)cell.accessoryView setOn:YES];   // Or NO, obviously!
    [(UISwitch *)cell.accessoryView addTarget:self action:@selector(mySelector)
         forControlEvents:UIControlEventValueChanged];
    

    希望有帮助!

    【讨论】:

    • 是的,我知道附件视图。在这种特殊情况下,我想使用自定义单元格,但谢谢!
    • [单元格 addSubview:mySwitch];没有必要。 cell.accessoryView 保留了 mySwitch。
    • 我对你投了赞成票,但一个简单的赞成票似乎还不够“谢谢”。谢谢!有时我太专注于手头的问题,以至于忘记了框架中的这些小额外内容。
    • 如果有多个像这样的表格单元格,您会采取什么方法将各个开关附加到正确的目标?
    【解决方案3】:

    我不久前做过。 你应该改变你的选择器

    [self.keychainSwitch addTarget:self action:@selector(keychainOptionSwitched:) forControlEvents:UIControlEventValueChanged];
    

    然后将您的方法更新为

    -(void) keychainOptionSwitched:(id)sender {
    UISwitch *tempSwitch = (UISwitch *)sender;
    }
    

    现在 tempSwitch 是已更改的开关。

    【讨论】:

    • 这对我来说不起作用。不过,感谢您的建议。
    • 这里也没有用。我得到:[OptionsViewController toggleImage]:无法识别的选择器发送到实例 0x4b305c0'。请注意,在没有参数的情况下调用它可以正常工作(尽管我显然不知道是哪个开关在调用它!)
    • 糟糕,成功了。确保在添加目标操作时在选择器调用中包含冒号!这有效@selector(keychainOptionSwitched:),这不@selector(keychainOptionSwitched)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    • 2012-08-09
    相关资源
    最近更新 更多