My applications window is generated programmatically. I have a xib file with a menu in it but I really don't know how to link it correct.
The menu bar is empty, except for the bold application name. I tried a few programmatically solutions to link the existing menu or to create and add a completely new menu, but nothing happened.
Does anybody know why this happens? Could it be that there's code in my project which overrides the menu with the empty menu every time?
Is it possible to alter this kind of menu and add menuitems?
Hope you'd help me.
Cheers
Swift:
let nib = NSNib(nibName: "NameOfXIB", bundle: nil)
nib.instantiateWithOwner(self, topLevelObjects: &array)
Objective-C:
NSArray *array;
NSNib *nib = [[NSNib alloc] initWithNibNamed:#"MainMenu" bundle:nil];
[nib instantiateWithOwner:self topLevelObjects:&array];
In your "array" you have all the top level stuff from XIB.
Hold you objects strongly or they will get released.
Owner is the object where you have IBOUtlets that needs to get linked by instantiation.
Related
Xcode 6.1, OSX not ios, allows me to Control-drag from a button in MainMenu.xib to AppDelegate only. This is unfortunate for me because my IBAction must include view methods like [self setNeedsDisplay:YES] . I need to Control-drag it into my MyView file, which will tolerate them. This also makes more sense.
Control-dragging from the button to any file other than AppDelegate does nothing.
Identity Inspector > Class is set to MYView.
How can I make this work, and how does the fix work?
Also, why is it now restricted to AppDelegate? Perhaps a timing issue?
Thanks ahead,
Nick
Try dragging an empty object from the object library to the area where you see 'AppDelegate' then selecting it and setting its' class to 'MyView' then secondary dragging to that object to create the IBAction.
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'm new to Objective C coding and the MVC concept gives me some pain. My goal is to develop a Mac Application. I was able to create a .xib for the main window. It starts well.
My main NSWindow has its main NSView. In this NSView, I put 3 subwiews (using Interface Builder). What I want is to change the content of the 2nd subview (by loading the content from another XIB file, called SubWindow1.xib) when I click on a button placed in the 1st subview.
I'm able to catch the click and tried some "xib loading" code but it doesn't work (the content never appears in my 2nd subview).
What I did is:
put the NSButton (on the 1st subview)
put a NSObject on Interface Builder (class renamed CtMainWindow, "Ct" for Controler)
link the IBAction (changeToSubWindow1) and IBOutlet (vSubView2 which is my 2nd subview)
create the CtMainWindow class, create a VwSubWindow1 class (which extends NSView)
In changeToSubWindow1(), I wrote:
VwSubWindow1 * vProfile = [[VwSubWindow1 alloc] initWithFrame:vSubView2.bounds];
[vProfile loadXib];
[vProfile.superview addSubview:vProfile];
The loadXib() function does:
NSNib * nib = [[NSNib alloc] initWithNibNamed:[self #"SubWindow1"] bundle:nil]; //#"SubWindow1" is the name of the expected loaded xib without .xib extention
[nib instantiateWithOwner:self topLevelObjects:nil];
And Voila. I was hoping that loading the sub xib in a view, and putting that view in my 2nd subview, it would appear.
I also tried to put only the following code in changeToSubWindow1()
VwSubWindow1 * vProfile = [[VwSubWindow1 alloc] initWithFrame:vSubView2.bounds];
[vProfile loadSubWindow];
The loadSubWindow() function does:
[NSBundle loadNibNamed:#"SubWindow1" owner:self];
Without more success.
I already read lots of threads from stackoverflow and tried lots of solutions but none of them worked for me.
Can anyone give me the hint I need in order to load and display the Xib in a subview ?
Thanks in advance.
you can try this method
you can put 3 xib files and 3 windows. connect each window
self.packages = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[self.window1.contentView addSubview:self.vc.view];
self.packages.view.frame = ((NSView*)self.window1.contentView).bounds;
[window1 makeKeyAndOrderFront:NSApp];
I have created a baseview project in xcode4. I want to use a new xib file to instead of the old viewController.xib file. So I just change the old viewController.xib file's name. and I also change the MainWindows.xib, let the UIViewController direct to the new name one xib file.
All are ok, but the view are transparent in the MainWindows, like link the xib to UIViewController are not correct. I don't know..
My step are:
1. create a new xib file.
2. link the new xib file to MyUIViewController class
![I think link way is this,I don't know if is correct?]
Try other way:
If I use the xcode template to add sub UIViewController (include xib and class file), and add the code like:
testViewControllerViewController *Controller = [[testViewControllerViewController alloc] init];
self.viewController = Controller;
[Controller release];
//self.window.rootViewController = self.viewController;
[self.window addSubview:self.viewController.view];
[self.window makeKeyAndVisible];
The xib content are show correct.
If I change the name of xib file, the xib content are not show. Because I want to create the Class first, and use the old xib file.
Any body know how to resolve it: Create xib file and sub UIViewController separately.
If these are way to do this, There is a problem: I have two xib file and link to only one UIViewController, if I use the UIViewController, which xib is used?
So, I want to sure whether can we create the xib file and sub UIViewController separately?
Why we must set the Custom Class file to SUB UIViewController, show as the picture above.
I'm not sure if I understand the problem correctly, but are you asking why you must always add the Controller's view as a subview to the main window?
The iPhone hierarchy is quite simple: every App has a main window, with a controller. This controller has a View, most of the time.
So, to make your app do something, and show something you will need to add the Controlling logic (from the Controller) and the View that it's controlling to the main window, by calling
[self.window addSubview:[Controller View]];
I've looked around online, and haven't been able to find an acceptable solution to this problem...
I'm looking for a simple code pattern:
Load a TabBarController object (with associated subview controllers) from a separate .xib file, instead of including and loading automatically from a default MainWindow.xib.
In XCode terms, starting from a new iPad/iPhone project as a "Tab Bar Application", the goal is to solve the following:
Create the project
Move: TabBarController, TabBar, FirstViewController, and SelectedSecondViewController from MainWindow.xib, into a new "TabBarController.xib" file
After moving, MainWindow.xib should only contain: File's Owner, First Responder, App Delegate, Window
In TabBarController.xib, File's Owner and First Responder are set to: UIApplication and UIResponder, respectively.
Change "didFinishLaunchingWithOptions" in the main application delegate to the following:
REMOVE:
[self.window addSubview:tabBarController.view];
ADD:
UITabBarController *uiTab = [[UITabBarController alloc] initWithNibName:#"TabBarController" bundle:nil];
[self.window addSubview:uiTab.view];
With these changes, the application builds and runs, but when the TabBarController loads the tab bar is "empty" -- there don't appear to be any contents in the controller.
In looking in the debugger, either the "init" isn't initializing from the data correctly, or something in the .xib file is not set correctly.
What is the correct solution to this? I realize there are other ways of doing this, and yes, I have them working in other applications.
What I'm looking for however, is a specific solution using the default project, that can be used as a general pattern for setting up iOS code.
Thanks in advance for any help
js
I think i know what you are looking for because i want the same thing.
Create New Empty xib file at interface builder.
Add to the xib TabBarController from the library.
Edit whatever you need on this tab bar controller on the xib.
Of course, save...
Determine from which view controller do want to create that xib with tab bar controller. In other words, who is the view controller that will cause this tab bar controller to appear.
Let's call that view controller ParentViewController
In that view controller, create an IBOutlet to a TabBarController.
Back to the xib, make the identity of the File's Owner to the ParentViewController and of course dont forget to hook up the outlet of the tab bar controller in the file's owner to the tab bar controller in the xib.
save the xib and you are ready to go.
When you want to present that tab bar, just decide which way you want to do it: Modally,Popup or something else (Not inside a navigation controller because Apple dont allow tab bar controllers to be inside navigation controllers).
When you decide, just present your tab bar controller outlet the way to present any other view controller. for example:
[self presentModalViewController:self.myTabBarController animated:YES];
Assuming you start with the "Tab Bar Application" template and move the UITabBarController and associated view controllers to a new nib as you described...
In your new nib, File's Owner should be set to your AppDelegate class. Then connect the outlet "tabBarController" of File's Owner to the UITabBarController.
Then in your -[application:didFinishLaunchingWithOptions:], do not remove this line:
[self.window addSubview:tabBarController.view];
Instead, load the new nib right before that with your app delegate as the owner:
[[NSBundle mainBundle] loadNibNamed:#"TabBarController" owner:self options:nil];
That will set your tabBarController property (since you made that connection in the nib) and then you can proceed as normal. What you were doing was actually creating a whole new UITabBarController, and not loading the one from the nib at all. (well, ok you were loading it for a brief moment, but then not doing anything useful with it)
Hope that helps.