cocoa - 如何使 NSTableView Row 内的按钮响应所表示的对象

标签 cocoa nstableview cocoa-bindings nstablecellview

我已经和这个问题斗争了一段时间了。我正在开发文件复制管理器模块,到目前为止,除了取消按钮之外,我已经能够使一切正常工作。由于某种原因,当我单击特定行的取消按钮时,按钮操作同时针对多行。

File Copy Manager

经过几天的研究这个问题,我能够使用以下方法使对象成功取消该行所代表的操作:

-(IBAction)btnCancelOperationClick:(id)sender {
    NSInteger row = [_tableView rowForView:sender];
    if (row != -1) {
        FileCopyOperation *opr = [_fileCopyOperations objectAtIndex:row];
        [opr cancel];
        [_fileCopyOperations removeObjectAtIndex:row];
        [_tableView removeRowsAtIndexes:[NSIndexSet indexSetWithIndex:row] withAnimation:NSTableViewAnimationEffectFade];
    }
}

这很好用,我可以取消操作并相应地更新我的表。其他一切都按预期工作,但我的代码或绑定(bind)一定有问题。我从 Nib 加载此单元格,然后使用以下方法注册此 Nib :

[_tableView registerNib:[[NSNib alloc]initWithNibNamed:@"FileCopyCell" bundle:nil] forIdentifier:@"FileCopyCell"];

我将 QueueController 设置为文件的所有者,并像这样 Hook 所有内容:

Bindings

如果有人能指出我正确的方向以使这件事正常工作,我将不胜感激。提前致谢!

编辑以添加更多代码示例。

-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    FileCopyCell *cell = [tableView makeViewWithIdentifier:@"FileCopyCell" owner:self];
    FileCopyOperation *opr = [_fileCopyOperations objectAtIndex:row];

    [cell.fileName setStringValue:[NSString stringWithFormat:@"Copying \"%@\"",opr.fName]];
    [cell.progressBar setDoubleValue:((opr.bWritten.doubleValue / opr.fSize.doubleValue) * 100)];
    [cell.totalBytes setStringValue:[NSString stringWithFormat:@"of %@",[NSByteCountFormatter stringFromByteCount:opr.fSize.longLongValue countStyle:NSByteCountFormatterCountStyleFile]]];
    [cell.status setStringValue:[NSString stringWithFormat:@"%@",[NSByteCountFormatter stringFromByteCount:opr.bWritten.longLongValue countStyle:NSByteCountFormatterCountStyleFile]]];
    [cell.icon setImage:[[NSWorkspace sharedWorkspace]iconForFile:opr.srcURL.path]];
    [cell.cancelButton setTarget:self];
    return cell;
}

-(void)windowDidLoad {
    [super windowDidLoad];
    _fileCopyOperations = [NSMutableArray new];
    windowFrame = [self.window frame];
    rows = 0;

    [_tableView registerNib:[[NSNib alloc]initWithNibNamed:@"FileCopyCell" bundle:nil] forIdentifier:@"FileCopyCell"];

    if (!fileCopyManager) {
        fileCopyManager = [FileCopyManager sharedFileCopyManager];
        [fileCopyManager.fileCopyQueue addObserver:self forKeyPath:@"operationCount" options:NSKeyValueObservingOptionNew context:(void*)fileCopyManager];
    }

    [_scrollView setHasHorizontalScroller:NO];
    [_scrollView setHasVerticalScroller:NO];
}

最佳答案

最好的方法是子类化 NSTableCellView 并让它处理自己的操作和表示的对象。例如,表示 Foo 实例的单元格可以具有两个属性:foofooController。当调用 (nonatomic) foo setter 时,单元格可以更新自己的 UI 以表示传递的 Foo。当 Foo Controller 创建表格单元格时,它可以实例化一个 FooCell 实例,将自身设置为 fooController 并分配 Foo code> 实例并让cell 自行处理。取消按钮的目标可以是它自己的单元格,当调用 -cancel: 操作时,它可以告诉它的 fooController 做什么(因为 Foo Controller 负责更新队列和 TableView ),并且由于它具有对其 foo 的引用,因此它可以通过某些 -cancelFoo:(Foo * )theFoo 方法,而不依赖于 Controller 来查找其索引(如果您对行的出现和消失进行动画处理,或者用户快速连续取消一堆,但它们的删除被延迟和更新,则这可能不准确)异步)。

又漂亮又干净。整齐有序的遏制/职责分离。该单元处理自己的 UI 更新和操作,并知道自己的 foo; foo Controller 处理它的 foo 集合、它的 TableView 以及 foo 到 foo 单元格的分配。

关于cocoa - 如何使 NSTableView Row 内的按钮响应所表示的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29683926/

相关文章:

Iphone 对象 C - 数据、对象和数组

cocoa - 如何实现 'NSTableview Delegate'方法?

objective-c - 渐进式加载 NSTableView

objective-c - 涉及绑定(bind)时如何覆盖 NSError 表示?

swift - 在 Swift 中使用绑定(bind)以编程方式创建基于 View 的 NSTableView

macos - cocoa 在 NSTableView 内绑定(bind) NSTableView

objective-c - 在前向类中找不到属性 'frame'

objective-c - NSInvocationOperation 和 NSOperationQueue 并发

swift - MouseMoved 函数从未被调用

swift - 无法以编程方式将字典数组中的行添加到 NSTable