In my cocoa OS X application, I have a WindowController with a xib file, and Two ViewControllers with xib files, I have added a Custom View in the WindowController, Where I am swapping those two Sub Views by removing and adding those Views when clicked in continue or next button.
[[theViewController view] removeFromSuperview];
self.theViewController = [[WelcomeInstallViewController alloc] initWithNibName:newView bundle:nil];
[innerInstallerView addSubview:[theViewController view]];
[[theViewController view] setFrame:[innerInstallerView bounds]];
Now In one of those views i have a button which needs to disable the continue button in the WindowController.I have looked into NSNotificationCenter, this is my first mac,cocoa, objective c app. should i use NSNotificationCenter? i am confused, and didn't understand properly.
There are many ways to skin the cat..
The simplest approach would consist of adding an outlet to your NSWindowController and link the button to that outlet in Interface Builder, then handle the button enablement on whatever conditions you require.
Notifications are one good way of loosely coupling application components, e.g. in case the window controller doesn't initiate the state change that would trigger the button to disable/enable itself.
Other possibilities include NSUserInterfaceValidations, a dedicated mechanism (protocol) in Cocoa to..
allow the target of a user interface element such as a menu item or a toolbar item to decide whether or not the user interface element should be enabled.
Given a similar design requirement (multiple loadable XIBs), I have used the NSViewController paradigm to allow logic to be attached to the sub-views that I load into the main view. In this case, I would create an NSViewController subclass which has a bool property (let's call it canContinue), which I would bind from the main view's button to owner's subview.canContinue.
If you do this, the main view will have to load the view controller (which will take care of loading the XIB) when you bring in each of the individual subviews, and then make sure to assign the subview property in the owner to point to the NSViewController that you load.
Related
Most of the time, owners of xib is a UIViewController.
I sort of use it my self.
Still I am confused why.
I suppose, the viewDidLoad and viewWillAppear is kind of the main selling point.
Is that it?
What are the advantage of using UIViewController as owners of an XIB?
A UIViewController object is the main way for views to appear within an iOS window.
Apple provides this as a fundamental, foundational building block (along with so many others) which you can use to build upon quickly and get your app out to market.
And when you subclass UIViewController, you're able to do lots of beautiful customizations which can be collected and eventually turned into (hopefully decent) products. When you subclass a UIViewController, you need to set the "owner" of a XIB file to that subclassed view controller (e.g. ThioViewController), so that way the app knows what object (and user interface) is being instantiated.
Hopefully this isn't too super abstract of an explanation.
First, spend a bit time to understand MVC http://en.wikipedia.org/wiki/Model–view–controller
This is the milestone of Objective-C (not only) development.
UIViewController is controller for all your views (inside this viewController). It provide starting point for you to create views on the screen, manipulate the views, handle actions from views etc.
You can create UIViewController programmatically.
XIB is representation of the screen which you can comfortably operate in Interface Builder to create and customize design of your application screen or one of the screens.
Since XIB represent the screen(view) it must be the controller which controls all the view on the screen - UIViewController or UINavigationController or other type of controller depending of your needs.
Most of time you will subclass UIViewController and use it to achieve you goals.
UIViewController have several subclasses which inherit directly from it (UINavigationController, UITabBarController).
Also UIViewController hav several methods (some of them)
-(void)viewDidLoad
This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method. You usually override this method to perform additional initialization on views that were loaded from nib files.
and
-(void)viewWillAppear:(BOOL)animated
Parameters
animated
If YES, the view is being added to the window using an animation.
Discussion
This method is called before the receiver’s view is about to be added to a view hierarchy and before any animations are configured for showing the view. You can override this method to perform custom tasks associated with displaying the view. For example, you might use this method to change the orientation or style of the status bar to coordinate with the orientation or style of the view being presented. If you override this method, you must call super at some point in your implementation.
Please check Apple documentation for more information
https://developer.apple.com/LIBRARY/IOS/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html
I have a UIView containing a login form, however when the user is already logged in, I want to show a logout button instead of the form.
My current approach is creating a subview for both the login form and the login button, overlapping each other in Interface Builder.
I would then only show one of the subviews at a time.
Is there a better way of doing this so it is easier to design in Interface Builder, while still using the same UIViewController?
If it matters the view is a modal view.
You could tweak your UIViewController to actually be a UITabBarController, but tweak the tab bar so that it's not visible when the controller is pushed to the screen:
self.hidesBottomBarWhenPushed = YES;
This should allow you to:
Programmatically switch between views easily
Manage two (or more) separate UIViewController instances in IB easily, without overlapping
For optional / modal parts of a view controller, one approach I've used several times in the past is to create a view for each section as top level objects in the nib. You can arrange each view using interface builder more easily then, and then all you need to do in your code is conditionally add the appropriate view to the main view in your viewDidLoad method. Remember that, as top-level objects in the nib, they should have strong outlets, not weak outlets.
Is it possible to access a NSWindowController's element from a child NSViewController?
Essentially I have a NSProgressIndicator that spins on the bottom corner of the NSWindow. This works because my WebView is in my NSWindowController instead of my NSViewController.
I want to break the logic apart now but I'm having trouble understanding how I'd access these elements from my View Controller.
Thanks!
You can't connect an outlet from one NIB to an object in another and the desire to do so indicates a problem with your design. If the view is so intimately connected to other things in the window, maybe it shouldn't be separated out into a different NIB.
A view should only go into a separate NIB when it makes sense as a self-contained unit. It should represent and manipulate its controller's representedObject and not much more. The controller might have a delegate that it informs about what's being done and asks to make customizing decisions.
Maybe you can continue to use a separate NIB if you adopt that sort of design. Perhaps the window will have a reference to some model object. It would configure the view controller to use that model object as its represented object. And perhaps the progress indicator would be bound to that same model object. Then, as the view manipulates its represented object, it would indirectly also affect the progress indicator.
Another option would be for the window controller to set itself as the delegate for the view controller and your view controller could invoke it at appropriate points to inform it of things going on in the view. Then the window controller could do whatever was appropriate to the progress indicator or other stuff in the window outside of the view. This hypothetical delegate is something you would have to add to the view controller class and you'd design its protocol.
Assume you do not have a UIController to do the job. From inside the UIView .. how would you replace self with another UIView?
It's not very clear what you are trying to do from your question. UIController is not a class, for instance.
Ideally your app should be structured something like this:
UIViewController subclass
Controls a set of objects that are all on screen at one time. For example, any number of UITextFields, UIButtons, UIViews and UILabels.
has methods (IBActions and other delegate methods) which are triggered by user interaction with the controls and inputs.
has IBOutlets which allow it to manipulate what the user sees on screen. For instance an IBOutlet attached to a UILabel allows changing the text when a user presses a button.
UIView is only generally subclassed if you need custom drawing code, or some kind of custom control. Don't put application logic here if you can help it, and you can usually help it.
You can have multiple UIViewControllers but they usually function very independently. Often View Controllers don't maintain references for other view controllers. If they do it's loose couplings like the delegate pattern.
Bottom line: if you have two views controllers that need to communicate with each-other, you need to have a reference to one from the other. This usually occurs in the form of a property on one or both of the view controllers, and is connected either by interface builder or at run time when you create them.
You can add another subview using self.addSubview: you may also want to check self.bringSubviewToFront:
For more information, check the docs:
http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html
I've a single window Document-based application that loads several NSViewControllers that serve as the main view. Each view controller is a self-contained class that deals with certain business needs and as such implements all methods necessary to work.
My problem is how to make the toolbar work when a specific view controller is loaded. I've no problems wiring the toolbar to a delegate and the toolbar items to actions as long as these are implemented in the window class. But if I try to set a new action for a toolbar item on the loadView method of a view, the toolbar item simply ignores it and continues calling the method on the main window class.
So, how can I dynamically change the action on a toolbar item?
Are you setting the target as well? (ie [foo setTarget:] in addition to [foo setAction:])
Presumably your window controller has some sort of currentViewController ivar/property? It might be better not to reassign the toolbar actions when switching view controllers, and instead use the window controller to pass them on the currently active view controller.