4

私はかなり長い間この問題と戦ってきました。私はファイル コピー マネージャー モジュールに取り組んでいます。これまでのところ、キャンセル ボタンを除いてすべてを完全に機能させることができました。何らかの理由で、特定の行のキャンセル ボタンをクリックすると、ボタン アクションが複数の行を同時にターゲットにします。

ファイル コピー マネージャー

問題を数日間調査した後、次を使用して、行で表される操作をオブジェクトにキャンセルさせることができました。

-(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];
    }
}

これはうまく機能します。操作をキャンセルして、それに応じてテーブルを更新できます。他のすべては意図したとおりに機能しますが、コードまたはバインディングに何か問題があるはずです。このセルを nib からロードし、次を使用してこの nib を登録します。

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

QueueController をファイルの所有者にし、次のようにすべてをフックしました。

バインディング

このことを適切に機能させるために誰かが私を正しい方向に向けることができれば幸いです。前もって感謝します!

編集してコード サンプルを追加します。

-(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];
}
4

2 に答える 2

4

最善のアプローチは、サブクラスNSTableCellView化し、独自のアクションと表現されたオブジェクトを処理できるようにすることです。たとえば、インスタンスを表すセルは、とのFoo2 つのプロパティを持つことができます。( )セッターが呼び出されると、セルは独自の UI を更新して、渡された を表すことができます。コントローラーがテーブル セルを作成するとき、インスタンスをインスタンス化し、それ自体を設定してインスタンスを割り当て、セルにそれ自体を処理させることができます。キャンセル ボタンのターゲットは独自のセルにすることができ、アクションが呼び出されたときに何をすべきかを伝えることができます (foofooControllernonatomicfooFooFooFooCellfooControllerFoo-cancel:fooControllerFooコントローラーはキューとテーブルビューを更新する責任があります)そしてそれはその への参照を持っているので、コントローラーに依存してそのインデックスを検索することなく、foo何らかの方法でそれをコントローラーに渡すことができます(あなたが-cancelFoo:(Foo *)theFoo行の表示と非表示を再アニメーション化するか、ユーザーが一連の行をすばやくキャンセルしているが、それらの削除が遅れて非同期に更新されます)。

素敵できれい。きちんと整理された封じ込め/責任の分離。セルは独自の UI 更新とアクションを処理し、独自の foo を認識します。foo コントローラーは、その foo コレクション、そのテーブル ビュー、および foo セルへの foo の割り当てを処理します。

于 2015-04-17T13:53:22.557 に答える
1

Joshua Nozzi のおかげで、彼の推奨に従って、ボタン アクションをコントローラーからセル クラスに移動しました。cell クラスでは、以下のメソッドを使用して、表現されたオブジェクトにアクセスし、[operation cancel]メッセージを送信しました。

-(IBAction)cancelOpr:(id)sender {
    NSButton *button = (NSButton*)sender;
    FileCopyOperation *opr = [(NSTableCellView*)[button superview]objectValue];
    [opr cancel];
    // This code calls the controller [removeObject:] method that takes care of cleaning everything out and updates the GUI accordingly.
    AppDelegate *ad = (AppDelegate*)[[NSApplication sharedApplication]delegate];
    QueueWindowController *qc = [ad getQueueController];
    [qc.fileCopyOperations performSelectorOnMainThread:@selector(removeObject:) withObject:opr waitUntilDone:YES];
}

完全なプロジェクトはこちらから入手できます。

ここに画像の説明を入力

于 2015-04-20T12:29:37.257 に答える