This one is stumping me, though I know it's going to be simple.
I have multiple ViewControllers, each of which has a table view to display a list of data specific to the controller. Three out of the 4 work perfectly. However, I'm clearly missing something in the forth, because the Delegate methods are never getting called by .reloadData(). No compiler errors, just never calls my delegate methods for some reason.
Here is my class setup including my connected outlet variable:
class performanceViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
//--------------------------------
// OUTLET CONNECTIONS
//--------------------------------
#IBOutlet weak var displayPerformanceList: NSTableView!
I've also implemented the following two delegate functions:
func numberOfRows(in tableView: NSTableView) -> Int {
and
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
but for some reason, neither of these functions are called when I execute my custom function:
func redrawViews() {
self.displayPerformanceList.reloadData()
}
(Note: the .reloadData is wrapped in a function because it will be doing other things as well that I haven't added in yet.)
I added breakpoints in both of the delegate functions, which is how I know they are not getting executed.
I know this is going to turn out to be something stupid that I missed since I have it working in three other custom viewControllers... I just can't for the life of me figure out what I missed...
Any thoughts would be greatly appreciated!
:)
Well, after poking around a bit more and following some tutorials, I found my problem. I completely forgot to link the NSTableView Data Source and Delegate to the controller in the Interface Builder!
Doh!
Leaving this question/answer here in case anyone else gets caught by this. :)
Related
I want to create a swipable tableview same as it is present in the IOS. But I am not able to find any document related to that. Also I was going through the NSTableView Documentation and fund the following.
/* View Based TableView: rowActionsVisible can be queried to determine if the "row actions" (see: tableView:rowActionsForRow:edge:) are visible or not. Set rowActionsVisible=NO to hide the row actions. Setting rowActionsVisible=YES is currently not supported and will throw an exception. This property is not encoded in the nib.
*/
#property BOOL rowActionsVisible NS_AVAILABLE_MAC(10_11);
At the end of the Comment it says Setting rowActionsVisible=YES is currently not supported and will throw an exception. So, how are we going to set the action?
Any leads would be appreciated.
So the new Swipeable table functionality was added in MacOS 10.11, and it looks like the way to do it is via implementing the NSTableViewDelegate method:
optional func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge edge: NSTableRowActionEdge) -> [NSTableViewRowAction]
Where you can set up NSTableViewRowAction objects via a relatively straightforward init method.
I used NSCollectionView in my application. In certain condition i want to hide and Unhide the NSCollectionView. But it will not hide the NSCollectionView.
I used the following code
#IBOutlet weak var thumbnailView: NSCollectionView!
func applicationDidFinishLaunching(aNotification: NSNotification) {
thumbnailView.hidden = true
NSThread.sleepForTimeInterval(5)
thumbnailView.hidden = false
}
Note: Sleep the thread just for demonstration purpose
Also Hiding the NSScrollView is not working.
EDIT: I perform same code on Button Touch up Inside event i get the same result. It does not hide my CollectionView.
#IBAction func ButtonnISClick(sender: AnyObject) {
thumbnailView.hidden = true
NSThread.sleepForTimeInterval(5)
thumbnailView.hidden = false
}
Here are things that are wrong with your code (mostly because you did not provide enough information in your question):
Use lowercase strings when naming variables (so change ThumbnailView to thumbnailView;
I don't know where are you writing this code. Is it NSWindowController, NSViewController or NSWindow subclass? Depending on the location, you should write 2nd to 4th lines in different methods (either windowDidLoad(), viewDidLoad() or awakeFromNib()
Update: Given your code is in application did finish launching and you are sleeping in that method, you won't see any changes, since the window of your app is presented only after the method has returned (i.e. all code has been executed). I suggest you to move this code into a subclass of either NSWindowController's windowDidLoad (I'm not sure about that one) or NSViewController's viewDidAppear: method.
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell = tableView.dequeueReusableCellWithIdentifier("HeaderCell") as! CustomHeaderCell
You can see the code above. I just wanted to ask that how and why we can, or should, set a tableViewCell as a Class? In this case it is CustomHeaderCell. For further info about the code here's the thing: I am just creating a custom header by following a guide I saw in web.
You should use this pattern when (a) you know the actual class of the object being returned, whereas the compiler can't reasonably know this; and (b) you need to then use the methods/properties of this subclass.
In this case, you probably have a cell prototype in your storyboard that specifies a CustomHeaderCell base class (or you have registered a class or NIB such that you know that the HeaderCell identifier will return a CustomHeaderCell instance). Furthermore, you presumably want to reference the properties of this CustomHeaderCell (e.g. setting the text property of its custom UILabel outlets or whatever).
Despite so much advantages of swift lang, one of the reason I did not adopt swift code is its bad code completion support with Xcode.
Here are two scenarios to better describe my question.
Scene 1:
During daily app development, I may come across quite a few protocol methods. Take the following UITableViewDataSource method
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
for example, after typing
func tableView(tableView: UITableView,
, I will normally type [tab] key, but there are nothing to promote in swift lang.
while things go smoothly in Objective-C:
So most of the cases, I have to jump to UITableView(wait a 1-2 secs for Xcode to generate swift header), and copy the method needed, then paste it the place I was coding.
By the way, if you [command + left] the method pasted above, Xcode has no idea what the function is, and where it is defined.
Scene 2:
To tweak animation, I need to change a method to an alternative one with more args.
//from
class func animateWithDuration(duration: NSTimeInterval, animations: () -> Void)
//to
class func animateWithDuration(duration: NSTimeInterval, animations: () -> Void, completion: ((Bool) -> Void)?)
In Objective-C, I gonna stroke [tab] before the last closing parenthesis, everything works fine. When I do this in swift, just a tab(four blanks) will appear.
My questions are:
How do you accomplish the two scenes I described above?
Are there some better way to do the same job for swift?(Maybe a plugin available out there, or any other helpful tips)
This is something I also despise while writing code in swift. There is no great way to do this, therefore you have to choose your method before you let it autocomplete.
For both scenario 1 and 2, you would have to type the first letters of tableView and animateWithDuration respectively, and use the up and down arrows to choose your method, and hit tab to finish the entire method.
The plus of swift is that it will automatically fill in func or class func, but after you fill in the methods, you can't add or remove parameters.
So far I can't find an easier way to do this. You'll have to wait for apple to improve their autocomplete.
I've read plenty about the How-To about moving data across view-controllers in Swift iOS programming but so far I haven't found a big consensus:
Temporary models (Unnecessary I think for small data)
Variable/Placeholders
Protocols
Others...
The rules about references and pointers in Objective-C may not apply for Swift, so values flying over in memory with protocols may not be the same, or I don't know (that's why I'm asking).
So, in a very simple but well-done manner, if I have a variable say... - result - of String type in a ViewController1 how can I make it available in a ViewController2? I don't need an Strong link to it, just the value.
Which way would you recommend?
Thank you all very much for your answers.
A common way to "jump" from viewController1 to viewController2 is via a storyboard segue. This segue can be performend in several ways: Directly from storyboard (i.e. from a button) or by code, using performSegueWithIdentifier method from a UIViewController.
No matter which way the segue is performed, the method prepareForSegue is called immediately before the segue is performed. In this method you get a reference to the segue's target viewController where you can pass your variable.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let viewController2 = segue.destinationViewController as ViewController2 {
// passing variable from vc1 to vc2
viewController2.result = self.result
}
}