で、テキストを折り返し(wrap)設定にすると、テキストが入るText Fieldはちゃんと折り返ししてる感じなんだけど、セルの高さはそのままでは変わらないもんだから表示されないんですよねー。
たとえばこれ、「あいうえおかきくけこ」って入れたのに「あいうえおかきくけ」までしか表示されないという。
で、色々考えてみた。
1. そもそもセル毎の高さってどうやって変えるのよ?
tableView(tableView: NSTableView, heightOfRow row: Int) -> CGFloat
っていうのがあるようです。これの戻り値がそれぞれのセルの高さになります。
他の場所、例えばviewForTableColumnの中でtableView.makeViewWithIdentifierを使ってTableCellViewを取得して、それの高さを設定したとしても、セル毎の高さではなく、残念ながら全てのセルの高さに適用されるんですよね。
だから、どうにかしてText Fieldの高さを取得して、このheightOfRowの戻り値に設定してやれば出来そうなんですよね。
2. どうにかって、どうやってText Fieldの高さを知るのよ?
はじめは、
tableView.makeViewWithIdentifier(tableColumn!.identifier, owner: self) as! NSTableCellView
でCellViewを取得して、これのtextField.bounds.heightを使えばいいんじゃないかと思ったんですけどダメでした。この高さ、テキスト折り返した後も何にも変わってない。
正解は
textField.attributedStringValue.boundingRectWithSize(CGSizeMake(
CellView.frame.width, CGFloat.max), options: .UsesLineFragmentOrigin, context: nil)
とやって領域情報(NSRect)を取得して、これのheightを使えばよいみたいです。
実際にやったこと
Table View CellのLayoutを「Wraps」に、Line Breakを「Character Wrap」にした。
Autoresizingはこんな感じになっている。おそらくデフォルト。
で、コードは以下のとおり
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSTableViewDataSource, NSTableViewDelegate {
@IBOutlet weak var window: NSWindow!
@IBOutlet weak var tableView: NSTableView!
@IBOutlet weak var txtCell1: NSTextField!
@IBOutlet weak var txtCell2: NSTextField!
@IBOutlet weak var btnPost: NSButton!
//TableViewで扱う値が入った配列
var tableArray:[NSDictionary] = []
//行数(配列の数)を返す
func numberOfRowsInTableView(tableView: NSTableView) -> Int
{
return self.tableArray.count
}
//配列更新時に呼び出される カラムのidentifierを元に、そのカラムのTableCellView内のTextFieldの内容を変更
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView?
{
let cellView = tableView.makeViewWithIdentifier(tableColumn!.identifier, owner: self) as! NSTableCellView
cellView.textField?.stringValue = tableArray[row][tableColumn!.identifier] as! String
cellView.textField?.frame.size.width = cellView.frame.width //TextFieldをセルの横幅にあわせる
return cellView
}
//tableViewセルの高さ指定
func tableView(tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
let tableColumn1 = tableView.makeViewWithIdentifier("tableColumn1", owner: self) as! NSTableCellView
//viewForTableColumnで文字列を入れてもここでは反映されてなくて高さが取得できないので、ここでも入れる
tableColumn1.textField!.stringValue = tableArray[row]["tableColumn1"] as! String
let rect1 = tableColumn1.textField!.attributedStringValue.boundingRectWithSize(CGSizeMake(
tableColumn1.frame.width, CGFloat.max), options: .UsesLineFragmentOrigin, context: nil)
let tableColumn2 = tableView.makeViewWithIdentifier("tableColumn2", owner: self) as! NSTableCellView
//viewForTableColumnで文字列を入れてもここでは反映されてなくて高さが取得できないので、ここでも入れる
tableColumn2.textField!.stringValue = tableArray[row]["tableColumn2"] as! String
let rect2 = tableColumn2.textField!.attributedStringValue.boundingRectWithSize(CGSizeMake(
tableColumn2.frame.width, CGFloat.max), options: .UsesLineFragmentOrigin, context: nil)
if(rect1.size.height > rect2.size.height) {
return rect1.size.height
} else {
return rect2.size.height
}
}
@IBAction func btnPost(sender: NSButton) {
self.tableArray.append(["tableColumn1": self.txtCell1.stringValue, "tableColumn2": self.txtCell2.stringValue])
self.tableView.reloadData()
}
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
}
そんなこんなで折り返されたテキストに合わせてセルの高さが変更されました。
めでたしめでたし