I'm adding a toolbar programmatically inside an interface inheriting NSObject <NSToolbarDelegate>, and implementing these methods:
- (NSToolbarItem*)toolbar:(NSToolbar*)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)willBeInsertedIntoToolbar;
- (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar*)toolbar
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
I also add a button by calling setView on a NSToolbarItem. This view contains an NSButton and is in the .XIB interface.
However, setAction on the same item does not work, due to reason described at http://www.cocoabuilder.com/archive/cocoa/291782-nstoolbaritem-custom-view-setaction.html#291783.
How do I implement this solution?
You could set the target and action of the NSButton in the nib file itself, or if you need to do it programmatically, then create an IBOutlet to the NSButton and do it in code.
When you use an NSButton in a toolbar item, it effectively acts like an NSButton would anywhere else in your interface, rather than as an NSToolbarItem per se. For example, you won't be able to easily disable or enable the button through the use of the standard -validateToolbarItem: or -validateUserInterfaceItem:; rather, you'll need to have an IBOutlet to the button in question, or otherwise use bindings to enable or disable the button.
Related
How can I programmatically select an NSToolbar item?
[toolbar setSelectedItemIdentifier:[theToolbarItem itemIdentifier]]
This code only selects it. I want to send it's action too, so that it changes panes.
You could set the target and action of the NSButton in the nib file itself, or if you need to do it programmatically, then create an IBOutlet to the NSButton and do it in code.
When you use an NSButton in a toolbar item, it effectively acts like an NSButton would anywhere else in your interface, rather than as an NSToolbarItem per se. For example, you won't be able to easily disable or enable the button through the use of the standard -validateToolbarItem: or -validateUserInterfaceItem:; rather, you'll need to have an IBOutlet to the button in question, or otherwise use bindings to enable or disable the button.
I have a Document based application. I want to add a contextual menu that displays context-sensitive info when the user right-clicks selected text in an NSTextView.
I have followed the advice in the Apple documentation and
Added an NSMenu as a root object in my XIB file.
Connected the NSMenu instance to the menu outlet of the NSTextView.
Connected an IBAction to the NSMenuItem inside the NSMenu.
So far so good. Every thing works as expected: the menu item appears and the action is called when it is selected.
I need to get the selected text from the NSTextView before the menu appears so that I can configure my menu item appropriately. According to the docs
If you need to customize the contextual menu, you can do so by setting
an appropriate object as the menu’s delegate and implementing the
menuWillOpen: method to customize the menu as you see fit just before
it appears.
I connect the delegate of the NSMenu to File's Owner. None of the delegate methods are called. ( menuWillOpen: is the only one I need, but I've tried others, too).
I set a breakpoint inside the IBAction that gets called when the menu item is selected. If I inspect the menu with the debugger I can see that the delegate is correctly set to the object that implements the delegate method.
Is there anything else to check? Anything I'm doing blatantly wrong?
Xcode v4.6.3
SDK v10.8
Deployment target 10.7
After some digging, this is what I found: NSTextView builds a different NSMenu instance to use as the contextual menu, probably by overriding -menuForEvent: or some similar internal method. This new menu copies the menu items from the menu you created in Interface Builder (in fact, it creates new menu item instances whose attributes are copied from the original menu items) but it does not copy the menu delegate, which is why your menu delegate does not receive -menuWillOpen:. I am not sure whether this is intentional or not. Reading that documentation quote you posted, it seems to be a bug.
What you can do is to set the delegate of your NSTextView instance to an object whose class conforms to NSTextViewDelegate (maybe your File’s Owner, which already conforms to NSMenuDelegate) and implement the following method:
- (NSMenu *)textView:(NSTextView *)view menu:(NSMenu *)menu forEvent:(NSEvent *)event atIndex:(NSUInteger)charIndex
{
// if the menu delegate is not self, set another object
[menu setDelegate:self];
return menu;
}
This will make sure that the contextual menu created by the text view uses your delegate.
NB: since NSTextView creates a different contextual menu, it could be the case that it might want to set the menu delegate to itself or some other internal object. In my tests the delegate is nil, so it looks like it’s safe. Alternatively, you could discard the proposed menu argument and return your own NSMenu instance with the delegate correctly set.
Finding this thread saved me a lot of time...thanks! Here's an implementation that works in an NSView in Swift. myNSMenu is an outlet from Storyboard to appDelegate and a subclass of NSMenu. Without the assignment of the delegate in the code below, the NSMenuDelegate functions were not called.
let appDelegate = NSApplication.sharedApplication().delegate as! AppDelegate
appDelegate.myNSMenu.delegate = appDelegate.myNSMenu
NSMenu.popUpContextMenu(appDelegate.myNSMenu, withEvent: theEvent, forView: self)
I'd like to create a custom NSTableCellView instantiated by Interface Builder. I've set my Table Cell View class to MyTableCellView, and properly created MyTableCellView : NSTableCellView .m/.h files.
However, I just can't CTRL+Drag a simple button from inside this view to MyTableCellView.h in order to create an IBOutlet.
Here is a video to show what happens: http://youtu.be/sNNbuVT-SZs.
How the view is subclassed:
How I try to CTRL+Drag a button
Also, sometimes, Interface Builder just don't allow the cell view's class to be modified. What's happening ?
I finally found a solution, that is a little weird but works as expected. Instead of connecting the NSButton to MyTableCellView header directly, I used the reversed path:
Manually create an outlet:
#property(retain, nonatomic) IBOutlet NSButton* button;
Then click the empty circle on the left, and drag it to your XIB file's button:
I have no idea why it works this way, please let me know if you know the anwser.
I have a NSWindow with an NSView and an NSTextField inside.
I'm using Interface builder right now. I have dropped the two controls on the default NSWindow and subclassed an NSView. I'm implementing the -drawRect method from NSView and I need to access to the content of NSTextField.
How do I refer to the instance of NSTextField from a method inside the NSView ?
Your NSWindow is (or should be) controlled by a window controller. In IB you create an outlet for the NSTextField in your window controller. Using the outlet, you can then refer to the NSTextField:
In your window controller .h file:
#property (strong) IBOutlet NSTextField *myTextField;
In your window controller .m file:
#synthesize myTextField;
From there you can in your controller:
[[self myTextField] setEditable: NO];
A point to note is that you do not access the controls in a window directly from that window as windows (and all Cocoa controls for that matter) are statically stored in a XIB/NIB file. All access to controls (UI elements) is channelled through controllers (NSWindowController, NSViewController) which in turn are capable of loading XIB/NIB files.
Apple provides various samples in their docs on how to do this.
I have Uitable view within uiview with navigation bar , I want to add button to the navigation bar to edit the contents of uitableview
any suggestion how to do that please
I think that you want to place your UITableView controller within a UINavigationController (see the UINavigationController class reference for more information).
In your UIViewController for the UITableView, you need to override the methods found under the "Configuring a Navigation Interface" section of the Apple Developer Documentation.
Within this section of methods lies - (UIBarButtonItem *)editButtonItem, which you could override to provide the button for your editing purpose. Under the hood, the UINavigationController will call this method to get the edit button for its user interface. Using this technique ensures that your app stays consistant with the user expierence iOS users have come to love.
There is solution that I tried and worked for me. The solution is
in .h file
UIBarButtonItem *edit;
and set property line as
#property (nonatomic , retain) IBOutlet UIbarButtonItem *edit;
in .m file
in your action handler of the button add
[self.tableView setEditing:TRUE];
Open the .xib file of your view controller and add a UIBarButtonItem either to left or right side of the Navigation Bar and connect the respective IBOutlet to edit button and also the selector method.
Now in the delgate of tableView add the following method
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
//sets the editing style for every row.
return UITableViewCellEditingStyleDelete;
}
Now you can play around with the UITableViewDelegate Methods and also the above methos to get the desired functionality.
Hope it works and do communicate if it does!!