2014-01-17 19 views
5

iOSアプリケーションをMacに移植しようとしていますが、移行中にいくつかの問題が発生しました。それらの1つはNSTableViewのカスタマイズです。 NSCell,NSTableRowViewとカスタムNSViewの違いは正確には何ですか?NSTableview?私は最初にNSTableViewに基づいてビューを開始しましたが、私はすぐに自分で選択を処理しなければならないことに気付きました。私はそれを取り除くことができませんでしたので、私はNSTableRowViewを使いました。それは不思議なことに、私のカスタムNSTableRowViewのイニシャライザーを呼んでいません。ビューベースのNSTableView選択の強調表示

私は基本的に、選択可能なカスタムコンテンツを持つカスタムテーブルビューセルを必要としています。それを行う最善の方法は何ですか?

iOSでは、UITableViewCellをサブクラス化し、selectedViewプロパティを設定します。 Macではこれよりも複雑なようです。

答えて

16

私は実際に(サイドバーに)この質問を見つけました。サブクラスNSTableRowViewに助言しています。私はすでにそれを前にしていたが、うまくいかなかった。しかし、この答えは非常に有益ではないので、私は私が作るためにやっているカバーしようとする...

Handling custom selection style in view based NSTableView

を私は再びそれを試してみましたが、非常に驚​​くべきことは、動作するようになりましたこの作品。

まず、次のNSTableViewデリゲートメソッドを実装し、nilを返します。

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

    return nil; 

} 

ベースのビュー(私は... NSTableViewRowが同様にビューベーステーブルを考えていると思います)あなたは、このメソッドを実装する必要がテーブルを使用するためには。私は何が間違っているかもしれないことは確かではありませんが、この方法がなければ、私の細胞は表示されません!

NSTableViewは、このプロパティを設定することで、任意の選択を処理させないようにしてください:

yourNSTableView.selectionHighlightStyle = NSTableViewSelectionHighlightStyleNone; 

わかりましたので、今、私たちは、次のデリゲートメソッドで我々の細胞を設定したい:

-(NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row{ 

    static NSString *cellID = @"cell_identifier"; 

    //use this if you want to reuse the cells 
    CustomTableRowView *result = [tableView makeViewWithIdentifier:cellID owner:self]; 

    if (result == nil) { 

     result = [[CustomTableRowView alloc] initWithFrame:NSMakeRect(0, 0, self.frame.size.width, 80)]; 
     result.identifier = cellID; 

    } 

    result.data = [tableData objectAtIndex:row]; 

    // Return the result 
    return result; 

} 

さて、今度はサブクラスNSTableRowViewをサブクラス化し、次の2つのメソッドを実装/オーバーライドします。

まず、setSelected:をオーバーライドする必要があります。セルが選択されたときに背景を再描画するようにします。だからここにある:先に述べたように、私たちはその背景を再描画するセルのためにsetNeedsDisplay:を呼び出す

-(void)setSelected:(BOOL)selected{ 

    [super setSelected:selected]; 
    [self setNeedsDisplay:YES]; 

} 

最後に、描画コード。方法このようなdrawBackgroundInRect:オーバーライド:

+1

私は最初のビットは必要ないとわかりましたが、残りは+1に役立ちました。ありがとう。 – lateAtNight

+0

@lateAtNight喜んでそれを助けました:) –

+0

誰かを助ける場合、私は10.9でSwiftを使ってこれをやろうとしていましたが、CGContextRefを取得するのはちょっと違います。この回答を参照してください:http://stackoverflow.com/a/24056236/2708274 – Matt

2
-(void)drawBackgroundInRect:(NSRect)dirtyRect{ 
    if (!self.selected) { 
     [[NSColor clearColor] set]; 
    } else { 
     [someColor set]; 
    } 
    NSRectFill(dirtyRect); 
} 

をNSTableViewDelegateプロトコルtableViewSelectionDidChangeに応答して、次のコードを使用:

は、選択された行のNSTableRowViewを取得し、その上にsetEmphasizedメソッドを呼び出します。 setEmphasizedがYESに設定されている場合は、青いハイライトが表示されます。いいえ、グレーのハイライトが表示されます。

-(void)tableViewSelectionDidChange:(NSNotification *)aNotification { 

    NSInteger selectedRow = [myTableView selectedRow]; 
    NSTableRowView *myRowView = [myTableView rowViewAtRow:selectedRow makeIfNecessary:NO]; 
    [myRowView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleRegular]; 
    [myRowView setEmphasized:NO]; 
} 

及び青色次いでグレーセットのダンスの影響を回避する

[_tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone]; 
+0

このアプリケーションに戻る以外の他のアプリケーションをクリックすると、選択した行が再び青色になります。 – Jacky

2

スウィフトでthe_criticの溶液:(XCodeの7ベータ3で試験し、スイフト2.0)

class CustomTableRowView: NSTableRowView { 

    override var selected: Bool { 
     willSet(newValue) { 
      super.selected = newValue; 
      needsDisplay = true 
     } 
    } 

    override func drawBackgroundInRect(dirtyRect: NSRect) { 
     let context: CGContextRef = NSGraphicsContext.currentContext()!.CGContext 

     if !self.selected { 
      CGContextSetFillColorWithColor(context, NSColor.clearColor().CGColor) 
     } else { 
      CGContextSetFillColorWithColor(context, NSColor.redColor().CGColor) 
     } 

     CGContextFillRect(context, dirtyRect) 
    } 

} 

のViewController:

class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource { 

    // [...] 

    func tableView(tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? { 
     guard let rowView = tableView.makeViewWithIdentifier("RowView", owner: nil) as! CustomTableRowView? else { 
      let rowView = CustomTableRowView() 
      rowView.identifier = "RowView" 
      return rowView 
     } 

     return rowView 
    } 

} 
関連する問題