UISwitch 和 UITableViewCell iOS4

发布于 2024-09-16 07:37:47 字数 2814 浏览 8 评论 0原文

Caveat: I have looked for the answer to my question and several come close, but I'm still missing something.场景如下:

我想要一种方法来根据表中的数据(我可以做到)在运行时动态创建包含 UISwitchUITableViewCell 。问题在于连接开关,以便在视图更改(导航离开、关闭等)时我可以获取它们的值。我尝试使用事件 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:

Caveat: I have looked for the answer to my question and several come close, but I'm still missing something. Here is the scenario:

I want a way to create UITableViewCells that contain UISwitches dynamically at run time, based on the data in a table (which I can do). The problem becomes connecting the switches such that I can get their value when that view is changed (navigated away, closed, etc). I have tried to use the events UIControlEventValueChanged to be notified, but have failed to specify it correctly, because it dumps when that switch is tapped. Also, there doesn't seem to be any way to uniquely identify the switch so that if all the events are handled by a single routine (ideal), I can't tell them apart.

So...

If I have a UITableView:

@interface RootViewController : UITableViewController 
{
    UISwitch * autoLockSwitch;
}

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

// the .m file:

@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;
}

and finally:

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

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

Questions:

  1. Why would it crash (bad selector) when the switch was tapped? I believe that my code follows all the example code that I have seen, but obviously something is wrong.

  2. I cannot put a instance method into a table as a function pointer; and it doesn't seem to like a class method either. If I make it a 'C/C++' function, how do I get access to the class/instance member variables? That is, if I want to put a call to autoLockSpecialItem into a static table (or reasonable facsimile) such that I can get autoLockSwitch member variable? If I make it a class method and the autoLockSwitch var a static, will that be valid?

  3. More simply: how do I connect the UIControlEventValueChanged to my view (I have tried and failed) and can I differentiate at runtime within the event handler which switch has changed?

  4. Is there a better way? I cannot believe that I am the first person to have to solve this type of problem.

Apologies for the length, appreciation for attention and grateful for any and all help.

:bp:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷了相思 2024-09-23 07:37:47

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

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

Don't know about why your method isn't connected, but a simple way to "differentiate at runtime within the event handler which switch has changed" is to take the (id)sender given to your event handler, walk your tableview, and compare the sender to any switches, if present, in each table item. If that's too slow, a hash table connecting senders to table cells, or something like that, is a possible optimization.

If you want to use C function pointers, you need to pass the object to the function to use it to call the object's property accessor methods within the function. (Or you could assign the object to a global variable if it's clearly a singleton, but that's a very politically incorrect answer.)

嗳卜坏 2024-09-23 07:37:47

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

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

First, and easy way to define your different switches would be defining their tag based on the row number. When one of the switches is tapped you can access sender.tag to get the row number this way.

Also, you should probably be adding the switch the the cells content view, not the actual cell, [cell.contentView addSubview:autoLockSwitch]. Also the frame does need to be set (note CGRectZero, cocoa will ignore the width and height but uses the x,y coords to define where you want the switch in the cell.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文