NSTableView带复选框单元格

6
在将NSTableView添加到Xcode 4的xib中后,我设置它有4列。第一列是一个简单的列,将包含项目名称。其余3个是复选框。我从对象库中拖动了一个Check Box Cell到tableview。
我填充了表格,出现了复选框,但是如果我单击它们,什么都不会发生,我无法选中或取消选中它们。此外,我甚至不知道如何通过代码操作。
我该怎么办:能够选中或取消选中复选框,并从代码中获取它们的状态。
我已经看过这个问题,但它没有真正回答我的问题。
这里是一些处理表格的代码,如要求所示:
- (int)numberOfRowsInTableView:(NSTableView *)tableView
{
    return (int)[myArray count];
}

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
    if([[tableColumn identifier] isEqualToString:@"col1"])
    {
       return[NSNumber numberWithInt:NSOffState];
    }    

    return [myArray objectAtIndex:row];
}

- (void)tableView:(NSTableView *)tableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    NSLog(@"%d", [anObject boolValue]);
    if([[tableColumn identifier] isEqualToString:@"col1"])
    {
        NSLog(@"click col1");
    }        
    if([[tableColumn identifier] isEqualToString:@"col2"])
    {
        NSLog(@"click col2");
    }        

}

我刚刚添加了更多代码。如何设置它进行选中/取消选中?


你能否编辑你的问题并展示-tableView:setObjectValue:forTableColumn:row:的实现?-tableView:objectValueForTableColumn:row:的实现也会有所帮助。 - user557219
你要插入什么类型的对象到数组中?你是如何将对象的内容映射到四列中的?你的代码将整个对象映射到了四列中。 - user557219
我有一个包含字符串的数组,它们位于第一列。然后我卡住了。请看我刚添加的代码。 - Mr Aleph
1个回答

8

模型

您需要决定一个模型,即如何表示在表格视图上显示的数据。例如:

// SomeObject.h
#import <Foundation/Foundation.h>
@interface SomeObject
@property (copy) NSString *name;
@property (assign,getter=isVisible) BOOL visible;
@property (assign,getter=isOpaque) BOOL opaque;
@property (assign,getter=isAnimatable) BOOL animatable;
@end

// SomeObject.m
#import "SomeObject.h"
@implementation SomeObject
@synthesize name, visible, opaque, animatable;
- (void)dealloc {
    [name release];
    [super dealloc];
}
@end

Nib文件

为了回答这个问题,让我们假设表格的列标识符与SomeObject中的属性名称匹配。

将模型中的值提供给表视图

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
{
    // Retrieve the model object corresponding to `row'
    SomeObject *obj = [myArray objectAtIndex:row];

    // Return the object property corresponding to the column
    if([[tableColumn identifier] isEqualToString:@"name"])
    {
        return obj.name;
    }
    // Since this method has return type `id', we need to box the
    // boolean values inside an `NSNumber' instance
    else if([[tableColumn identifier] isEqualToString:@"visible"])
    {
        return [NSNumber numberWithBool:obj.visible];
    }
    else if([[tableColumn identifier] isEqualToString:@"opaque"])
    {
        return [NSNumber numberWithBool:obj.opaque];
    }
    else if([[tableColumn identifier] isEqualToString:@"animatable"])
    {
        return [NSNumber numberWithBool:obj.animatable];
    }

    return nil;
}

使用表视图中的值更新模型

- (void)tableView:(NSTableView *)tableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    // Retrieve the model object corresponding to `row'
    SomeObject *obj = [myArray objectAtIndex:row];

    // Set the object property corresponding to the column
    if([[tableColumn identifier] isEqualToString:@"name"])
    {
        obj.name = anObject;
    }
    // Since the new value (`anObject') is an object, we need to
    // convert it to `BOOL' by sending it `-boolValue'
    else if([[tableColumn identifier] isEqualToString:@"visible"])
    {
        obj.visible = [anObject boolValue];
    }        
    else if([[tableColumn identifier] isEqualToString:@"opaque"])
    {
        obj.opaque = [anObject boolValue];
    }        
    else if([[tableColumn identifier] isEqualToString:@"animatable"])
    {
        obj.animatable = [anObject boolValue];
    }
}

使用键值编码可以使这段代码更简单,但在掌握表视图数据源之后再进行练习。 :P

谢谢,一切都好,但obj是什么?SomeObject可以是任何东西。如果我传递声明为NSInteger的行,则不起作用。除此之外,我不知道如何将复选框设置为ON或OFF(NSOffState或NSOnState)。 - Mr Aleph
1
@MrA obj 是您要插入数组中的对象。您不能简单地拥有一个字符串数组:复选框对应的值将存储在哪里?这就是为什么我声明了一个 SomeObject 类,其实例保留一个字符串(用于第一列)和三个布尔值(用于其他三列)。对于没有混合状态的复选框,您可以将它们的开启和关闭状态视为布尔值。 - user557219
谢谢,现在更清楚了。所以除了填充数组之外,我需要声明一个新对象来填充表格吗?或者我可以使用此数组(NSMutableArray)来完成此操作? - Mr Aleph
1
@MrA 的想法是您有一个可变数组(myArray),其中存储可以表示所有四列的类的实例(一个字符串,三个布尔/整数值)。在我的示例中,存储在数组中的元素是 SomeObject 的实例。另一个选项是将数组中的每个元素作为 NSDictionary - user557219
@MrA 为了测试,您可以将我放置在“模型”的部分代码添加到包含表视图数据源的同一实现文件(.m)中。虽然这不是项目通常组织的方式。至于对象,您可能想阅读一些面向对象编程的介绍。对于本问题而言,您可以(有点像)将它们视为C结构。 - user557219
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接