NSTableView のカスタム ヘッダーを作成しようとしています。ヘッダー テキストのフォントを変更し、境界線と垂直セパレーターを削除したいと考えています。
現在の上部と下部のヘッダーを以下に示します。
これを行う方法を知っている人はいますか?
更新: 修正を適用した後、ヘッダーは意図したとおりに表示されるようになりました。
NSTableView のカスタム ヘッダーを作成しようとしています。ヘッダー テキストのフォントを変更し、境界線と垂直セパレーターを削除したいと考えています。
現在の上部と下部のヘッダーを以下に示します。
これを行う方法を知っている人はいますか?
更新: 修正を適用した後、ヘッダーは意図したとおりに表示されるようになりました。
実際、mprudhom と Pronto からの両方の回答が、最終的な修正に大きく貢献しました。お二人に感謝します。
最終的な回答を投稿して、フォローしている人がどのように修正したかを確認できるようにすると思いました。
テーブルには NSTableHeaderView しかなく、TableHeaderCells がないため、mprudhom のコードだけを使用することはできませんでした。幸いなことに、Pronto がその問題を解決してくれました。
class MyTable: NSTableView, NSTableViewDataSource, NSTableViewDelegate
{
override func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView?
{
tableColumn!.headerCell = MyTableHeaderCell(textCell: tableColumn!.identifier)
}
}
mprudhom から直接 NSTableHeaderCell コードを使用しました。
final class MyTableHeaderCell : NSTableHeaderCell
{
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
override init(textCell: String)
{
super.init(textCell: textCell)
self.font = NSFont.boldSystemFontOfSize(14)
}
override func drawWithFrame(cellFrame: NSRect, inView controlView: NSView)
{
//super.drawWithFrame(cellFrame, inView: controlView)//, since that is what draws borders
self.drawInteriorWithFrame(cellFrame, inView: controlView)
}
override func drawInteriorWithFrame(cellFrame: NSRect, inView controlView: NSView)
{
let titleRect = self.titleRectForBounds(cellFrame)
self.attributedStringValue.drawInRect(titleRect)
}
}
これら 2 つのメソッドが実装されると、NSTableHeaderView が必要に応じて境界線なしで描画されたにもかかわらず、背景が灰色になるという最後の問題が 1 つ発生しました。そこで、このメソッドで NSTableHeaderView クラスをオーバーライドしました。
class ForecastHeaderView : NSTableHeaderView
{
required init?(coder: NSCoder)
{
super.init(coder: coder)
}
override init(frame frameRect: NSRect)
{
super.init(frame: frameRect)
self.wantsLayer = true
}
override func drawLayer(layer: CALayer, inContext ctx: CGContext)
{
super.drawLayer(layer, inContext: ctx)
layer.backgroundColor = CGColorCreateGenericGray(1.0, 1.0)
}
}
上記の回答は、viewDidLoadで直接使用することもできます
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableColumns.forEach { (column) in
column.headerCell.backgroundColor = NSColor.white
column.headerCell.drawsBackground = true
column.headerCell.isBordered = false
column.headerCell.attributedStringValue = NSAttributedString(string: column.title, attributes: [NSAttributedString.Key.font: NSFont.systemFont(ofSize: 13)])
}
}
NSTableHeaderCell
次のように、をサブクラス化して自分で図面を引き継ぐ必要があります。
final class CustomTableHeaderCell : NSTableHeaderCell {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(textCell: String) {
super.init(textCell: textCell)
self.font = NSFont.boldSystemFontOfSize(20)
}
override func drawWithFrame(cellFrame: NSRect, inView controlView: NSView) {
// skip super.drawWithFrame(), since that is what draws borders
self.drawInteriorWithFrame(cellFrame, inView: controlView)
}
override func drawInteriorWithFrame(cellFrame: NSRect, inView controlView: NSView) {
let titleRect = self.titleRectForBounds(cellFrame)
self.attributedStringValue.drawInRect(titleRect)
}
}
プログラムでテーブルを設定する場合は、次のようにします。
let col = NSTableColumn(identifier: id)
col.headerCell = CustomTableHeaderCell(textCell: title)
col.title = title
self.dataTableView.addTableColumn(col)
それ以外の場合は、Interface Builder でクラスの名前をサブクラスの名前に設定するだけでよいはずです。