I have an NSToolbarItem with an NSButton as its view and an NSMenuItem in the main menu. Both have the same action, which is sent to the first responder, not to a particular target. That method is ultimately implemented in a subclass of NSSplitViewController, somewhere in the view hierarchy of the window’s content view. I want to validate both items, but have that specific split-view controller take care of the validation, because it relies on some conditions local to that controller.
I overrode validateToolbarItem(_:) and validateMenuItem(_:) in that split-view controller. For the menu item, this is working as expected. The method is called and the validation happens. validateToolbarItem(_:) is never called, however.
According to Apple’s documentation, NSToolbar does not send validateToolbarItem(_:) to view-based toolbar items. To test this, I have substituted the toolbar item with an image toolbar item and there it works as expected.
Based on this, I have come across several solutions, but they aren’t quite what I want.
Subclass NSToolbarItem and override validate(). However, no guidance is given as to how I end up getting the controller’s validateToolbarItem(_:) to call.
Subclass NSToolbar and override validateVisibleToolbarItems(), then send messages to the first responder. Here I am running into the problem, that I cannot send a message to the split-view controller, because it is outside of the toolbar’s responder chain.
Subclass NSToolbar as above, but implement validateToolbarItem(_:) in a controller that is within the responder chain, such as the NSWindowController. This would work, but then I have to add additional code to handle what is not necessary for the menu item.
Is there an elegant solution for this that works as well like it does for the image toolbar item and the menu item?
I wrote the following code in my NSToolbarItem subclass for buttons. With this toolbarItem subclass, you can use normal validateUserInterfaceItem() or validateToolbarItem() to validate toolbar items that contain an NSControl.
override func validate() {
// validate content view
if
let control = self.view as? NSControl,
let action = self.action,
let validator = NSApp.target(forAction: action, to: self.target, from: self) as AnyObject?
{
switch validator {
case let validator as NSUserInterfaceValidations:
control.isEnabled = validator.validateUserInterfaceItem(self)
default:
control.isEnabled = validator.validateToolbarItem(self)
}
} else {
super.validate()
}
}
Related
So I tried everything with showing up the back button but it just won't work
This is how i arrange my View Controllers Used segue show from view controller to site view controller
And here is the site view controller that isn't showing back button
I even tried adding NavigationBar and a button with this function
self.navigationController.popToRootViewControllerAnimated(true)
Also failed
Update:
I tried this in both view controllers it's returning nil
in viewDidAppear and viewWillAppear
print(self.navigationController?.restorationIdentifier)
Once I got the same problem, when I was try to use view property of my UIViewController before it loaded properly. This caused problems with loading my navigation bar items. In fact, you should not touch view property until viewDidLoad method is called. Check, maybe it is your case, maybe you use view property in prepareForSegue method or in observers?
The latest update to NSCollectionView allows the delegate to detect the selection of items with
- (NSSet<NSIndexPath *>*)collectionView:(NSCollectionView*)collectionView shouldSelectItemsAtIndexPaths:(NSSet<NSIndexPath*>*)indexPaths
and
- (void)collectionView:(NSCollectionView*)collectionView didSelectItemsAtIndexPaths:(NSSet<NSIndexPath*>*)indexPaths
, among others.
However, insofar as I can tell, these methods only detect the selection of NSCollectionViewItem objects, and not any present header or footer views.
Are there any delegate methods to detect the selection of the header and/or footer views? If not, what is the best way to implement this detection?
Indeed these delegate methods are only for selecting items. If you want to do something when the header of footer view is clicked, you can add a gesture recognizer to those views yourself and hook it up to an IBAction on your controller.
I'm trying to build a To-do list application. I have 2 tablesviews and one textfield. In the first tableview are the different projects, and when you click on one of them the associated todos appear in the second tableview. It's a pretty basic Master-detail I guess.
I set it all up with bindings.
Right now the way you add a task, is you click on an add button and it adds a row with a placeholder text that's editable.
But what I want, is the user to enter the task in the textfield, press add, and then it adds the todo with the name already set.
So basically I have TodoItem Class with a name property, and my question would be, how do I get the content of the nstextfield and assign it to the name property ?
I tried creating an outlet from the Todoitem class to the textfield, but xcode won't let me connect it....
Tell me if you need to see any code, but since I used bindings, there's almost nothing to show. Thanks!
… how do I get the content of the nstextfield and assign it to the name property ?
Translate that directly into Objective-C:
NSString *contentOfTheNSTextField = [myTextField stringValue];
myNewTask.name = contentOfTheNSTextField;
You'd do that in the action method that you've set both the button and the field to call.
I tried creating an outlet from the Todoitem class to the textfield, but xcode won't let me connect it....
To do this, the Todoitem would need to reside in the nib.
But, even if you could do that, why should the model object know about the text field? Carrying values between model and view is a controller's job.
I've developed an app for Mac OS X Lion using its new view-based NSTableView, but as I want to port the whole app to Snow Leopard I'm trying to figure out the best way to emulate such a tableview. So far I've created a NSCollectionView and everything is fine, except for the fact that I can't get the index of the view from which a button click event is triggered.
In Lion I have the following function:
- (IBAction)buttonClick:(id)sender
so I can get the index of the view inside the tableview using a method (I can't remember its name) like
- (NSInteger)rowForView:(NSView *)aView
with aView being the sender's superview, but I couldn't find something similar for the collection view ... The only "useful" method seems to be
- (NSCollectionViewItem *)itemAtIndex:(NSUInteger)index
(or something like this), but this can't help me as it returns a NSCollectionViewItem and I can't even access it knowing only the corresponding view!
Within buttonClick, try this code:
id collectionViewItem = [sender superview];
NSInteger index = [[collectionView subviews] indexOfObject:collectionViewItem];
return index;
Hope this helps :)
Geesh! Both of those approaches have issues. I can see how the first on may work, but note that the "collectionViewItem" is actually the view, NOT the collectionViewItem, which is a view controller.
The second way will not work, unless you subclass the button and put in a back link to the collectionViewItem. Otherwise, your view does not know what collectionViewItem controls it. You should use a selector binding to the collectionViewItem's representedObject instead, to get the action to the correct object in your array.
How about something like:
id obj = [collectonViewItem representedObject];
NSInteger index = [[collectionView contents] indexOfObject:obj];
As I suggested here: How to handle a button click from NSCollectionView
I would do it like this (because the button you want to press should be coupled with the corresponding model, therefore the represented object):
Add a method to the model of your collectionViewItem (e.g. buttonClicked)
Bind the Button Target to Collection View Item
While binding set model key path to: representedObject
While binding set selectorname to: methodname you chose earlier (e.g. buttonClicked)
Add protocol to your model, if you must tell delegate or establish observer-pattern
use NSArrayController for binding to NSCollectionView,
use collectonViewItem.representedObject to get a Custom Model defined by yourself.
save and get index in your custom model.
That's works for me.
I have a tabview in which i have added 3 tabview Items.In each tab i have fields into which i want to populate data automatically. Which methods are invoked automatically when a tab is clicked.Please help me in this...
NSTabView allows you to specify an object as its delegate. This delegate object should be an instance of a class that conforms to the NSTabViewDelegate protocol. This protocol declares, amongst others methods,
-tabView:willSelectTabViewItem: to inform the delegate that a tab item is about to be selected;
-tabView:didSelectTabViewItem: to inform the delegate that a tab item has been selected.
You probably want to implement -tabView:willSelectTabViewItem: so that the fields are populated right before that tab item is selected.