【问题标题】:UISwitch and UITableViewCell iOS4UISwitch 和 UITableViewCell iOS4
【发布时间】:2010-08-26 19:19:17
【问题描述】:

警告:我已经找到了我的问题的答案,有几个已经接近了,但我仍然缺少一些东西。这是场景:

我想要一种在运行时根据表中的数据动态创建包含UISwitches 的UITableViewCells 的方法(我可以这样做)。问题在于连接开关,以便在更改视图(导航离开、关闭等)时我可以获得它们的值。我试图使用事件UIControlEventValueChanged 来获得通知,但未能正确指定它,因为当点击该开关时它会转储。此外,似乎没有任何方法可以唯一标识开关,因此如果所有事件都由单个例程处理(理想情况),我无法区分它们。

所以...

如果我有一个 UITableView:

@interface RootViewController : UITableViewController 
{
    UISwitch * autoLockSwitch;
}

@property (nonatomic, retain) UISwitch * autoLockSwitch;
-(void) switchFlipState: (id) sender;
@end

// .m 文件:

@implementation RootViewController
// ...


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    static NSString * CellIdentifier = @"Cell";
    int row          = 0;
    NSString * label = nil;
    TableCellDef_t  * cell_def = nil;

    row = indexPath.row;
    cell_def = &mainMenuTableCellsDef[ row ];

    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    label = (NSString *) mainMenuTableCellsDef[indexPath.row].text;
    [cell.textLabel setText:(NSString *) mainMenuItemStrings[ indexPath.row ]];
    if (cell_def->isSpecial)  // call special func/method to add switch et al to cell.
    {
        (*cell_def->isSpecial)(cell );  // add switch, button, etc.
    }
    else
    {
        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
    }
}


and this is the 'special' function:

-(void) autoLockSpecialItem :(UITableViewCell *) cell
{
    autoLockSwitch = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
    [autoLockSwitch addTarget:self action:@selector(switchFlipState:) forControlEvents:UIControlEventValueChanged ];
    [cell addSubview:autoLockSwitch];
    cell.accessoryView = autoLockSwitch;
}

最后:

-(void) switchFlipState: (id) sender
{
    NSLog(@"FLIPPED");
}

================================================ ===============

问题:

  1. 为什么当开关被点击时它会崩溃(错误的选择器)?我相信我的代码遵循了我见过的所有示例代码,但显然有问题。

  2. 我无法将实例方法作为函数指针放入表中;而且它似乎也不喜欢类方法。如果我将其设为“C/C++”函数,如何访问类/实例成员变量?也就是说,如果我想将对autoLockSpecialItem 的调用放入静态表(或合理的传真)中,以便我可以获得autoLockSwitch 成员变量?如果我将其设为类方法并将autoLockSwitch var 设为静态,那是否有效?

  3. 更简单地说:如何将UIControlEventValueChanged 连接到我的视图(我尝试过但失败了),我能否在运行时在事件处理程序中区分哪个开关已更改?

  4. 有没有更好的方法?我不敢相信我是第一个必须解决这类问题的人。

抱歉,感谢您的关注,感谢您提供的任何和所有帮助。

:bp:

【问题讨论】:

    标签: iphone objective-c uitableview ios4 uiswitch


    【解决方案1】:

    不知道为什么您的方法没有连接,但是“在运行时在事件处理程序中区分哪个开关已更改”的简单方法是获取给定的 (id)sender到您的事件处理程序,遍历您的表视图,并将发送者与每个表项中的任何开关(如果存在)进行比较。如果这太慢了,将发送者连接到表格单元格的哈希表或类似的东西是一种可能的优化。

    如果要使用 C 函数指针,则需要将对象传递给函数以使用它在函数内调用对象的属性访问器方法。 (或者你可以将对象分配给一个全局变量,如果它显然是一个单例,但这是一个政治上非常不正确的答案。)

    【讨论】:

      【解决方案2】:

      首先,定义不同开关的简单方法是根据行号定义它们的标签。当点击其中一个开关时,您可以访问sender.tag 以通过这种方式获取行号。

      另外,您可能应该添加切换单元格内容视图,而不是实际单元格[cell.contentView addSubview:autoLockSwitch]。此外,确实需要设置框架(注意CGRectZero,可可将忽略宽度和高度,但使用 x,y 坐标来定义您希望在单元格中切换的位置。

      【讨论】:

      • 谢谢。我认为 .tag 在 iOS4 中已被弃用——不是吗?为什么开关要连接到内容视图而不是单元格?如果我这样做了,开关还会随着单元格滚动吗?
      • 不,标签没有修饰,请查看标签属性的UIView 类参考。另外,请查看UITableViewCell contentView 的文档。 contentView 并不是单元格所有组件的超级视图。是的,开关仍会滚动。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-09
      • 2011-12-17
      • 1970-01-01
      • 2011-04-22
      相关资源
      最近更新 更多