I am creating tableView in my application programmatically, and I have this problem:
Whenever the content size of my tableView is bigger than its frame, the first row of tableView appears under the header initially, but it can be easily scrolled back into the position.
The screenshots of what the window looks like after the initial load.
Content size bigger than tableView frame(the issue is here):
Content size smaller than tableView frame(all good here):
My NSViewController class code:
class MainViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
let label: NSTextField = {
let label = NSTextField()
label.stringValue = "Test App"
label.font = NSFont.boldSystemFont(ofSize: 14)
label.textColor = .white
label.alignment = .center
label.drawsBackground = false
label.isBezeled = false
label.isSelectable = true
label.isEditable = false
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let labelContainerView: NSView = {
let view = NSView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let tableView: NSTableView = {
let tableView = NSTableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.usesAlternatingRowBackgroundColors = true
let column = NSTableColumn(identifier: .init(rawValue: "MyColumnID"))
column.headerCell.title = "Test"
column.headerCell.alignment = .center
tableView.addTableColumn(column)
return tableView
}()
let scrollView: NSScrollView = {
let scrollView = NSScrollView()
scrollView.hasVerticalScroller = true
scrollView.translatesAutoresizingMaskIntoConstraints = false
return scrollView
}()
override func loadView() {
view = NSView()
view.wantsLayer = true
}
var names: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
layoutUI()
for i in 1...9 {
let name = "Test \(i)"
names.append(name)
}
scrollView.documentView = tableView
tableView.delegate = self
tableView.dataSource = self
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let newCell = MyCellView(identfier: NSUserInterfaceItemIdentifier(rawValue: "MyColumnID"))
newCell.textView.stringValue = names[row]
return newCell
}
func numberOfRows(in tableView: NSTableView) -> Int {
return names.count
}
func layoutUI() {
view.addSubview(labelContainerView)
view.addSubview(scrollView)
labelContainerView.addSubview(label)
NSLayoutConstraint.activate([
labelContainerView.topAnchor.constraint(equalTo: view.topAnchor),
labelContainerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
labelContainerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
labelContainerView.heightAnchor.constraint(equalTo: view.heightAnchor,
multiplier: 1/5),
label.centerXAnchor.constraint(equalTo: labelContainerView.centerXAnchor),
label.centerYAnchor.constraint(equalTo: labelContainerView.centerYAnchor,
constant: -4),
scrollView.heightAnchor.constraint(equalTo: view.heightAnchor,
multiplier: 4/5),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
}
}
I would not recommend to setup a NSTableView in code. Its much easier to do this in Interface Builder and may prevent unwanted side effects. In any case if NSTableView is not displaying the first row as expected I would use scrollToVisible on the related NSScrollView to make the first row visible after loading the data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With