In the interface builder I see:
but in the built running app, I don't see my red text cell:
here's my Main.storyboard TableView in the Interface Build side panel:
it's just a normal table view dragged out from the UI Objects menu onto the Storyboard.
You might be missing the configuration required in NSTableViewDataSource and NSTableViewDelegate methods as follows. You need to set the dataSource and delegate of the NSTableView you just drag and dropped and implement numberOfRowsInTableView method for the class that conforms to these protocols.
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
return 1
}
Note: It would be best if you go through this tutorial which I found helpful for Cocoa development with NSTableView.
Related
Here is what I see on the storyboard. You can see the attributes of my table on the right:
Here is what I'm seeing after I launch the app:
I have not written any code that changes the view. It's all here in the storyboard. Everything is visible except the cells.
Xcode actually let you compile and run app with a tableview inside a UIViewController but It will show a blank table .. So instead of UIViewController embed static cell in UITableViewController . You can use ContainerView to get a static UITableView along with other controls on the same screen .. Embed tableViewController in containerView
Ray Wenderlich's website Blog Post says
One more thing about static cells, they only work in
UITableViewController. The Storyboard Editor will let you add them to
a Table View object inside a regular UIViewController, but this won’t
work during runtime. The reason for this is that UITableViewController
provides some extra magic to take care of the data source for the
static cells. Xcode even prevents you from compiling such a project
with the error message: “Illegal Configuration: Static table views are
only valid when embedded in UITableViewController instances”.
.
I was trying to mimic the Workout app for practise. And I got stuck at figuring out how to do this navigation from these table rows in the main screen to the 3/4 Workout starting screens which are page-based and seem to be hierarchical, with a back button on top left. They are most certainly not Modal as they do not appear from the bottom.
- - ->
However I did not find any way to connect a row to a set of page-based interface controllers with push segue.
This is what I tried:
1- presentController(withNames:, contexts:) which presents the page-based layout MODALLY.
override func table(_ table: WKInterfaceTable, didSelectRowAt rowIndex: Int) {
let controllers = controllersForExercise(categories[rowIndex])
presentController(withNames: controllers, contexts: nil)
}
func controllersForExercise(_ exercise: Exercise) -> [String] {
// Returns a bunch of Identifiers (from Storyboard) as [String]
}
2- In the storyboard, I connected the table row to the first of these page-based interface controllers by a push segue, and then connected that controller to the other three page-based interface controllers sequentially using nextPage segue (relationship).
This did not work. It just segues with the back button on top left but showed only the first interface controller, not the other three as page-based controllers.
I am assuming it is happening because table row selection makes it a hierarchical navigation while this is a page-based navigation, and the two cannot be mixed according to Apple.
So I am baffled about how Apple manages it themselves. Any clues?
OBJC:
+ (void)reloadRootPageControllersWithNames:(NSArray<NSString *> *)names
contexts:(NSArray *)contexts
orientation:(WKPageOrientation)orientation
pageIndex:(NSInteger)pageIndex;
SWIFT:
class func reloadRootPageControllers(withNames names: [String],
contexts: [Any]?,
orientation: WKPageOrientation,
pageIndex: Int)
I have a reoccurring problem that I have not found a clean solution for. I have a NSTableView in NSViewController that uses a subclass of NSTableView to implement the datasource and delegate protocols e.g.
class SecondEdit: NSWindowController, NSWindowDelegate {
#IBOutlet weak var subTrackTable: NSTableView!
var sublist = SubTrackListing()
func loadTable() {
// other stuff left out for brevity
subTrackTable.setDataSource(sublist)
subTrackTable.setDelegate(sublist)
subTrackTable.reloadData()
}
in particular it should be noted that the XIB file for the WindowController contains the Table and the outlet for the table is connected to the NSWindowController class.
class SubTrackListing: NSTableView, NSTableViewDataSource, NSTableViewDelegate {
Usual NSTableView Delegate etc functions
}
This works like a charm and properly displays all of the data and keeps the required NSTableView functions in their own (smallish) class (desirable in as the Window / ViewController classes get pretty bloated by themselves).
My Problem is that I have NOT found a way to get user edits from the Table's texfields. IF the windowController class was also the NSTableView datasource / delegate, it would be trivial. I would just hook up the textfields IBActions and grab the sender stringValues. In the subclassed case, although you can hook up the IBActions just like before, THEY NEVER FIRE. I have tried setting the NSTableView subclass in IBs Custom Class dialog and putting the textfields in the SubTrackListing class, but not only does IB fight you on this every step of the way (you can't just drag from IB to the NSTableView subclass, you have to code the IBAction in the subclass first and then - sometimes - you can drag from the IBActions circle to the textfield in IB and get a recognized hook up), the IBAction - even when Xcode seems to think it's hooked up - NEVER FIRES (!). So I ask what the _____ !is going on here and how can you get NSTableView input from a subclassed NSTableView.
And yes I could just shove the NSTableView functions into the NSWindowController class, but not only would there be the what if you have more than one table situation, I have the general feeling that there Ought to be A Way to DO THIS in a subclass. . .
Any help would be appreciated. . .
My app reads text files into [Card]. Each Card has a two-letter code at the front, and I break up the cards into different NSTableViews depending on that code. That lets me set the layout in IB so each group of cards has an appropriate display.
I used to have all of the controller code in a single VC, but as the number of tables grew, so did the complexity of this code. Since the views differ primarily in layout and some default settings, they can all descend from a single class. So I did:
class CardView: NSTableView, NSTableViewDataSource, NSTableViewDelegate { ...
and, for one example...
class GeometryView: CardView { ...
Then I went to IB, selected the tableview, and changed it's class to GeometryView. Now I have to set up the delegate and dataSource, and this is where I have my problem : IB will not allow me to drag either setting to either the GeometryView or CardView.
So... do the targets of these IB settings have to be a particular subclass, say NSViewController? Or is there something I'm missing that lets IB see these as targets? I didn't do anything in the original VC, it just worked. Or am I simply doing the wrong thing in IB?
In this image you can see the tableview on the far left, the custom view subclass in the helper, and the connections for the tableview on the right. Any attempt to drag from the connections to anywhere in the helper fails. Note that the two existing connections are to the former delegate VC, which is what I am trying to replace.
I'm not sure why Interface Builder won't let you connect the delegate or data source to itself, but you could do it programatically. The awakeFromNib method is probably the best place for this, as it's called after both initWithFrame and initWithCoder:
override func awakeFromNib() {
delegate = self
dataSource = self
super.awakeFromNib()
}
I created a custom hierarchy of views, somewhere in this hierarchy is a UITableView, with an outlet called TableView, so i can reach it from backend code.
I want to create and push a new view to the root viewcontroller's view stack when an item in that list is selected, but i can not find any relevant events on the UITableView.
All controls were defined using Interface builder in .XIB files
Am i looking in the wrong place?
thanks in advance.
Yes, you are looking in the wrong place. To use UITableView's "events", you have to implement a UITableViewSource and assign it to your table view. The most common way to do it is in the table view's controller as a nested class:
private class MyTableSource : UITableViewSource
{
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
// Do something for the selected row
}
// Override both RowsInSection and GetCell methods!
}
You then set the MyTableSource class to the table view's Source property:
myTableView.Source = new MyTableSource();
Note that the UITableViewSource class does not exist in Objective-C. It is merely a MonoTouch class that hosts both UITableViewDataSource's and UITableViewDelegate's methods, making things a lot simpler.
The RowSelected event happens in the UITableViewSource.