在按下按钮时从NSMutableArray填充NSTableView

时间:2015-04-01 20:30:18

标签: objective-c macos uitableview

在我正在开发的OSX应用程序中熟悉obj-c,我想填充一个TableView。花了几个小时读了太多博客文章,我无法理解如何在我的TableView中添加一行。

以下是我在this guide之后所做的事情:

我的NSMutableArray中有ViewController,此ViewController实现了接口NSTableViewDataSourceNSTableViewDelegate。我按照指南中的说明实施了两种方法。我还有一个按钮和一个tableView。当我点击按钮时,我用我自己的对象填充我的数组,这很好用。

但我现在想要的是,当我的数组被填充时,我的tableview也是如此。我知道我需要以某种方式绑定这两个,但我不知道怎么会有人给出一些指示?

以下是我的ViewController的代码:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableViewEpisodes.delegate = self;
    self.tableViewEpisodes.dataSource = self;
}

- (IBAction)btRefresh:(id)sender {

    CalendarReader* reader = [[CalendarReader alloc]init];
    self.episodes = [Episode getEpisodeFromEKEvents:[reader getLastMonthEventsForCalendarName:@"TV Shows"]];
    [self.tableViewEpisodes reloadData];
}

- (NSInteger)numberOfSectionsInTableView:(NSTableView *)tableView
{
    return [self.episodes count];
}

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColum row:(NSInteger)row {

    // Retrieve to get the @"MyView" from the pool or,
    // if no version is available in the pool, load the Interface Builder version
    NSTableCellView *result = [tableView makeViewWithIdentifier:@"MyView" owner:self];

    // Set the stringValue of the cell's text field to the nameArray value at row
    result.textField.stringValue = [self.episodes objectAtIndex:row];

    // Return the result
    return result;
}

2 个答案:

答案 0 :(得分:0)

首先,您正在创建一个带有您尚未声明的标识符的单元格视图,您需要执行以下操作(假设您在类中正确采用了UITableView协议):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  NSString *Ident = @"Ident";
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Ident];
  if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:Ident] autorelease];
  }

  [cell.textLabel setText: [yourArray objectAtIndex:indexPath.row];
  return cell;
}

这是NSTableView的委托方法。在加载视图时调用它,因此您需要在运行时提供数据源。

其次,我假设你想要一个行数与你的数据数组相等的行。如果是这样,则需要更改委托方法:

- (NSInteger)numberOfSectionsInTableView:(NSTableView *)tableView

为:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

最后,请记住以上方法填充ROWS,而不是现在填充的COLUMNS。填充数组后,需要调用方法:

[yourTableView reloadData]

为了刷新表格。

希望这会有所帮助。

答案 1 :(得分:0)

感谢@ bryan-wheeler,我在测试他的代码时发现了一条消息日志,我发现,我没有实现正确的方法:这是我现在ViewController的代码:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableViewEpisodes.delegate = self;
    self.tableViewEpisodes.dataSource = self;
}

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
    return 1;
}

-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex{
    return [self.episodes objectAtIndex:rowIndex];
}

对于像我这样的初学者,您还必须为存储在数据源数组中的类实现NSCopying协议。

现在,我的TableView中只有一个元素,它只显示了它的内存地址,但是一旦我发现如何让它在我的情况下适合未来的初学者,我就会更新这个答案。

编辑:好的,它的确有效!我的错误是:在tableView:objectValueForTableColumn:row:方法中,我虽然需要返回表示参数中给出的行的Object,但是我必须返回参数中给出的AND的单元,现在我发现了,这很明显,但作为法语,我没有正确理解方法名称。这是我现在的代码:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableViewEpisodes.delegate = self;
    self.tableViewEpisodes.dataSource = self;
}

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
    return [self.episodes count];
}

-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex{
    if([[aTableColumn title]  isEqual: @"Serie's name"]){
        return [[self.episodes objectAtIndex:rowIndex] seriesName];
    }else if([[aTableColumn title]  isEqual: @"Season number"]){
        return [NSString stringWithFormat:@"%ld", (long)[[self.episodes objectAtIndex:rowIndex] seasonNumber]];
    }else if([[aTableColumn title]  isEqual: @"Episode number"]){
        return [NSString stringWithFormat:@"%ld", (long)[[self.episodes objectAtIndex:rowIndex]episodeNumber]];
    }else{
        return nil;
    }
}

确实有一些优化可以随意提出。但它正在做这项工作。