将NSTableView填充并绑定到多个阵列控制器

时间:2012-07-30 02:08:25

标签: objective-c macos cocoa cocoa-bindings nsarraycontroller

我有一个API为NSArray提供了一堆内容对象 - 我们称之为acquiredFruit - 和一个名为likedFruit的空NSMutableArray。

我为两个数组创建了NSArrayControllers,并将我的TableView绑定到acquiredFruit.arrangedObjects。 tableView的第一列绑定到arrangedObjects.name并正确显示所有美味的水果。

我创建了一个带有复选框的第二列 - 当用户填写框时,我想将水果添加到我的likedFruit数组中。取消选中该框应该从likedFruit数组中删除水果对象。

基本上我希望我的NSTableView可以在两个阵列控制器之间加入。我觉得我应该为此制作一个单独的控制器,但我不确定如何解决这个问题。

我还应该提一下,我知道我可以遍历我的数组并使用我需要的字段构建另一个对象,但我的目标是通过使用绑定来实现,如果可能的话。

思想?

2 个答案:

答案 0 :(得分:3)

我认为你应该使用一个阵列控制器。

您可以在Fruit上使用名为liked的属性。现在,您的“已赞”复选框列已连接到arrangedObjects.liked。之后,当您想要确定所有喜欢的水果的集合时,您可以查询您的水果数组:

NSArray * likedFruits = [ allFruitsArray filteredArrayUsingPredicate:[ NSPredicate predicateWithFormat:@"liked = YES"] ] ;

如果你的UI的另一部分只显示喜欢的水果,你可以将数组控制器的filterPredicate设置为上面的谓词,以获得那些结果。

编辑:假设NSFruit是通过其他人的API提供的。让我们使用“将属性添加到其他人类的一般技术”:

@interface NSFruit (Liking)
@property ( nonatomic ) BOOL liked ;
@end

@implementation NSFruit (Liking)

-(BOOL)liked
{
    return [ objc_getAssociatedObject( self, "_abliked" ) boolValue ] ;
}

-(void)setLiked:(BOOL)b
{
    objc_setAssociatedObject( self, "_abliked", [ NSNumber numberWithBool:b ], OBJC_ASSOCIATION_RETAIN_NONATOMIC ) ;
}

@end

(我最近为100个帖子编写了相同的代码!)

答案 1 :(得分:1)

我现在不在我的Xcode电脑上,所以我无法测试这个,但看起来你真的不需要另一个阵列控制器,而只是另一个数组来保存likesFruits。我认为你需要从你的acquireFruits数组中创建一个字典数组,这个字典将有一个水果名称的密钥和另一个具有bool值的密钥,用于是否选中复选框 - 这个bool将绑定到你的第二列。我不确定下一步如何告诉likesFruit数组需要添加一个新的水果 - 我认为复选框可能有一个动作方法,你可以使用likeFruit数组添加对象单击复选框的行。

编辑后:

这是一个如何做我建议的例子。我将一系列水果变成一个字典数组(称为theData),其中包含复选框值的键(在IB中,数组控制器的内容数组绑定到Data,并且列绑定到Array Controller.arrangedObjects.fruitName和Array Controller.arrangedObjects.isLiked)。 checkChanged是一个连接到复选框的IBAction(但请注意发件人实际上是表视图),我使用复选框的值来确定是否将水果添加到likesFruits或删除一个。我再添加一个方法,连接到一个按钮,只是为了检查在likesFruits中的值。

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    self.theData = [NSMutableArray array];
    self.likedFruit =[NSMutableArray array];
    NSArray *acquiredFruits = @[@"Apple",@"Orange",@"Pear",@"Peach"];
    for (NSString *aFruit in acquiredFruits) {
        NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:aFruit,@"fruitName",[NSNumber numberWithBool:NO],@"isLiked", nil];
        [self.theData addObject:[dict mutableCopy]];
    }
    self.theData = _theData;
   // NSLog(@"%@",self.theData);
}



-(IBAction)checkChanged:(NSTableView *)sender { //connected to the button cell in the table view (but sender is the table view)
    NSString *theFruit = [[self.controller.arrangedObjects objectAtIndex:sender.clickedRow ] valueForKey:@"fruitName"];
    BOOL doWeLikeIt = [[[self.controller.arrangedObjects objectAtIndex:sender.clickedRow] valueForKey:@"isLiked"] boolValue];
    if (doWeLikeIt) {
        [self.likedFruit addObject:theFruit];
    }else{
        [self.likedFruit removeObject:theFruit];
    }
}

-(IBAction)logLikedFruits:(id)sender {
     NSLog(@"%@",self.likedFruit);
}