2012-07-30 80 views
1

我有一个API提供了NSArray和一堆内容对象 - 我们称之为acquiredFruit - 和一个名为likedFruit的空NSMutableArray。填充NSTableView并将其绑定到多个阵列控制器

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

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

基本上我想我的NSTableView加入两个阵列控制器之间。我有一种感觉,我应该为此做一个单独的控制器,但我不确定如何解决这个问题。

我还应该提到,我知道我可以迭代我的数组,并用我需要的字段构造另一个对象,但是我的目标是通过使用绑定来完成此操作,如果可能的话。

想法?

+0

你在另一个表显示这些likedFruits,或只需要他们在一个数组? – rdelmar 2012-07-30 03:11:27

+0

我希望我的acquireFruit绑定表中的行的已检查状态代表水果在likesFruits中的存在 - 我不需要另一个tableVlew,但我正计划在应用程序中的其他地方遍历喜欢的水果。 – arbales 2012-07-30 10:34:21

回答

3

我想你应该使用一个数组控制器。

您可以在水果上拥有一个名为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个职位!)

+0

啊,这是有道理的。如果NSFruit实际上是第三方API提供给我的对象?我是否需要包装它或写一个类别?我想我可以创建自己的ABFruit ... – arbales 2012-08-02 21:06:18

+0

我编辑了我的帖子,显示通过一个类别向NSFruit添加“喜欢”属性... – nielsbot 2012-08-02 23:02:38

+0

酷,我其实很熟悉类别,我只是总是犹豫使用它们。我听到有关这适当的时候的相互冲突的答案。 – arbales 2012-08-06 05:22:38

1

我现在不在我的Xcode计算机上,所以我不能测试这个,但是好像你并不需要另一个数组控制器,而只是另一个数组来存放喜欢的水果。我认为你需要从你的acquiredFruits数组中创建一个字典数组,这个数组将有一个水果名的关键字,另一个关键字的布尔值是否被选中 - 这个布尔值将被绑定到你的第二列。我不知道如何告诉likesFruit数组需要添加一个新的水果的下一步 - 我认为复选框可以有一个操作方法,您可以使用这个方法让favoriteFruit数组将对象添加到行点击复选框。

编辑完成后:

这里是一个如何做我建议的例子。我获取了一系列水果并将其转换为一个包含复选框值的键的字典数组(字符串数据)(在IB中,数组控制器的内容数组绑定到了数据,并且列绑定到了Array Controller.arrangedObjects.fruitName和Array Controller.arrangedObjects.isLiked)。 checkChanged是一个连接到复选框的IBAction(但注意发件人实际上是表视图),并且我使用复选框的值来决定是否向fruitsFruits添加一个水果或删除一个水果。我把一个更多的方法,连接到一个按钮,只是为了检查在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); 
} 
+0

你认为你可以详细说明一下吗? – arbales 2012-08-02 07:45:07

+0

@arbales,看我编辑的答案。 – rdelmar 2012-08-03 04:42:30

+0

谢谢@rdelmar,这个答案很有意义。这是从多个来源组成阵列控制器的一个很好的例子。我认为类别方法更适合我的用例,让我绑定到一个API提供的数组。对于其他场景,我一定会记住这一点! – arbales 2012-08-06 05:51:58