Merge cells of NSTableView - cocoa

Is there any way to merge cell's in a NSTableView?
I know there are two modes for displaying data in a NSTableView: cell-based and view-based. If the data are presented by cells, the function
tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int)
is responsable, otherwise
tableView(_ tableView: NSTableView, rowViewForRow row: Int)
Currently I'm using the first one. In iOS, you can use the cell prototype in interface builder to link the views with a custom UITableViewCell, but how can I achieve this for a complete row in a NSTableView?

Maybe I found a solution: You can use both
tableView(_:viewFor:row:)
and
tableView(:viewFor:tableColumn:row:)
but you have to be aware that the tableView is not using both methods for one cell (mutually exclusive).
Now you can define a xib, with a single UIView in it. Change the class of the UIView to NSTableRowView. Next, load the class in viewDidLoad into your table:
if let nib: NSNib = NSNib(nibNamed: NSNib.Name("SpecialRow"), bundle: nil) {
self.tableView?.register(nib, forIdentifier: NSUserInterfaceItemIdentifier("specialRow"));
}
In your table method rowViewForRow you can do the following:
if let srow: SpecialRow = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "specialRow"), owner: nil) as? SpecialRow {
// ...
return srow;
}

Related

Create a custom list on Storyboard Xcode

Being a beginner with Xcode, I wanted to know if it was possible to create a list with our own components? I explain, it would be to make a list of favorites scrolling on an Xcode view, with an image, a button to delete it, and a text. It is obvious that I will have to create more components but how to put them in a list without limits?
The prototype design is as follows:
Here !
Thank you in advance, Sincerely.
Yes you can make your own list cells. For that you will need to,
create your own UITableViewCell and add your componenents (2x UIImageViews, 1x UILabel)
register your cell to the UITableView you want to display the cell in with the identifier
Conform to both UITableViewDelegate & UITableViewDataSource
Refer this blog to learn more as I barely scratched the surface with the explanation
You can add data to the table as follows
/// Conforming to the UITableViewDelegate, UITableViewDataSource protocols
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// Table view to display data
#IBOutlet weak var tableview: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// setting the datasource and delegate
tableview.delegate = self
tableview.dataSource = self
}
/// 2d Array to store data
let data = [["Melon", "Glace"], ["Epinard"], ["one", "two", "three"] ]
func numberOfSections(in tableView: UITableView) -> Int {
return self.data.count
}
/// UITableViewDataSource protocol stubs
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.data[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell") as? CustomTableViewCell {
cell.name = data[indexPath.section][indexPath.row]
return cell
}
return UITableViewCell()
}
}

NSTableView Cell with Identifier keep giving nil

I am working on building MacOS app. I am trying to make table view that updates the cell when I press add button.
Following is my code:
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let identifier = tableColumn?.identifier as NSString?
if ( identifier == "NameCell")
{
var result: NSTableCellView
let cell = tableView.make(withIdentifier: "NameCell", owner: self) as! NSTableCellView
cell.textField?.stringValue = self.data[row].setting!
return cell
}
else if (identifier == "SettingCell")
{
if let cell = tableView.make(withIdentifier: "SettingCell", owner: self) as? NSTableCellView {
cell.textField?.stringValue = self.data[row].setting!
return cell
}
}
return nil
}
However, the line let cell = tableView.make(withIdentifier: "NameCell", owner: self) as! NSTableCellView is keep failing because it returns nil
fatal error: unexpectedly found nil while unwrapping an Optional value
NameCell is from
Can anyone please help me find a way to solve this problem?
For anyone else who comes here with this same question when trying to make an NSTableView fully programmatically: makeView(withIdentifier:owner:) WILL return nil unless a corresponding NIB exists for the given identifier:
NSTableView documentation:
If a view with the specified identifier can’t be instantiated from the nib file or found in the reuse queue, this method returns nil.
Likewise, the 'owner' param is a NIB-specific concept. In short: you cannot use this method if populating your NSTableView with cells programmatically.
In this answer, I detail the Swift code to produce an NSTableCellView programmatically: https://stackoverflow.com/a/51736468/5951226
However, if you don't want all the features of an NSTableViewCell, note that you can return any NSView in tableView(_:viewFor:row:). So you could, as per the CocoaProgrammaticHowtoCollection, simply write:
let cell = NSTextField()
cell.identifier = "my_id" // Essential! Allows re-use of the instance.
// ... Set any properties you want on the NSTextField.
return cell
You should set the "Identifier" with "NameCell" in the NSTableCellView. And your codes should simplified as follow since the column's identifier won't change for ever:
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
var result: NSTableCellView
let cell = tableView.make(withIdentifier: "NameCell", owner: self) as! NSTableCellView
cell.textField?.stringValue = self.data[row].setting!
return cell
}
references settings in XCode Interface Builder:

How to use two tableview in one view?

I have two table view in one view container. I insert each of them to the container.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
self.storyboard?.instantiateViewController(withIdentifier: "ChildTableView") as! ChildTableViewController
childTV.updateTable(id: indexPath.row)
}
I need to update second tableview when first tableview cell clicked.
How i can do this?
Okay, I think I see the problem. The way you've done this is with two UITableViewControllers and their table views. So now you have a problem communicating between the two table view controllers. But consider this: if you've truly created child view controllers, the table view controllers are children of the same parent. So the first table view controller can get its parent view controller, then get the parent's child view controllers, then get the second child view controller, and that must be the second table view controller.
In other words, if your view controller hierarchy is:
ParentViewController
TableViewController1
TableViewController2
... then TableViewController1 can say:
let tvc2 = self.parent!.childViewControllers[1] as! TableViewController2
... and now you have established a line of communication between them. So now table view controller 1 can talk to table view controller 2 and tell it to update its table. You will need to have a method in table view controller 2 that table view controller 1 can call, in order to hand it any needed data and tell it what to do.
in Second TableView:
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ChildTableViewController.updateTable(sender:)), name: NSNotification.Name(rawValue: "updateChild"), object: nil)
}
func updateTable(sender:NSNotification){
tableView.reloadData()
}
in First TableView:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
selectedItem["id"]=indexPath.row
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateChild"),object:selectedItem)
}

OSX Swift add image into nstableview

I have added a tableview and as well configured the cell with an identifier.
Everything works fine, the text of the cell gets displayed.
I have just one problem and don't know how to solve it.
How can I change the image of the tableview cell?
Here is my code:
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
let cellView = tableView.makeViewWithIdentifier("cell", owner: self) as! NSTableCellView
cellView.textField!.stringValue = self.objects.objectAtIndex(row) as! String
return cellView
}
How can I change the image which is also present inside the cell?
The standard NSTableCellView with text and image has an outlet imageView
cellView.imageView!.image = NSImage(named:"MyImage")

How to create two NSTtableView in one View?

I have one NSTableView (for OSX, not iOS), and in my ViewController class, which datasource for this table, I have two functions to fill this table:
func numberOfRowsInTableView(tableView: NSTableView) -> Int
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView?
Everything is fine with this table. But I need another NSTableView in the same View. What I should do to have second table?
Set the identifier of each table. Inside your delegates; numberofRowsInTable etc, check for which table triggered the call like this;
if aTableView.identifier == "table1Identifier"
{
// handle table 1 here
}
else
....
then return values for the correct table as needed.

Resources