I have a simple requirement.
On Click of a + button, I am trying to add a custom view to a SplitView.
I have created a class MyCustomView which is a subclass of NSView
In the applications nib file, I have a custom view which contains the buttons etc.
Now How to allocate a new MyCustomView every time ?
Is there an example to do this?
I am hoping something like
MyCustomView *v1 = [[MyCustomView alloc] init];
..
..
[splitView addSubView:v1];
[splitView addSubView:v2];
...
Please help
It's hard to tell exactly what you're describing based on your description but let's see if I understand you. You want to add a "copy" of your custom view assembly into a split view each time "+" is clicked, right?
The absolute best way to do this is to put the custom view assembly that will be copied (the "prototype") in its own xib. For each object you want to represent, you will instantiate a new copy from the xib and give it to some owner then add it to some parent view (a split view in your case ... odd for an unlimited number of views, but I don't have enough detail to say otherwise).
So. In the modern Cocoa world, such a view assembly should likely have its own view controller (NSViewController). This makes things easier for you since the xib's File's Owner will be an instance of your MyCustomViewController, whose -view is connected to the main container view in the xib (your custom view with all its subviews) and whose -representedObject is set to whatever model object your custom view represents. Your app will then maintain a list (an array or a dictionary, perhaps) of all the view controllers for the model objects. See this SO question/answer for a run-down of how to load from nibs/xibs.
This is basically how an NSCollectionView works (though the views must all be the same size - might not work for you). The collection view corresponds to your split view in this case; NSCollectionViewItem corresponds to your MyCustomViewController (and in fact on 10.5 and above NSCollectionViewItem is a subclass of NSViewController); your custom view is the collection view item's main -view. For each model object in its collection, it instantiates an NSCollectionViewItem and loads the view prototype from a xib (ideally, but this is optional), and uses this to set the item's view, then it sets the item's represented object (the model object).
I hope this clarifies things a bit. You've got some reading to do in order to understand enough of the nuts and bolts, but if you're still stuck, you might try editing your question to clarify or opening a new, more specific question.
Related
I've got a user interface that looks pretty much like iTunes. For purposes of encapsulation, the top area and the main table view are in separate classes with separate nibs. I want to bind the search field from the top view controller to the tableview in the bottom view controller. I've arranged it so there are properties to store the NSArrayController in both classes. The array controller is an array of dictionaries, and the dictionaries have a "search_keywords" key that I want to use to filter the tableview.
Is it possible to set up the search stuff in Interface Builder even though it's in a separate nib? I can't figure out what to put in the various boxes.
If it's not possible with IB, I assume it's possible in code, since there is a view controller with references to both of the sub-view controllers and I can get at the search field, table view and array controller objects through properties on the two classes.
How do I set it up? IB would be best, if it's possible.
What I did was use the NSSearchField in the top view controller as a dummy/placeholder. I create the "real" search field in the tableview's nib, and wire up all the bindings stuff as per normal. Then in the main view controller I grab the search field out of the tableview's nib, and replace the dummy searchfield with the real one using replaceSubview:with:
Now I can continue to use IB to modify the bindings, and it doesn't really matter what's in what nib as it all gets placed properly in the view hierarchy at runtime.
In your concept you cannot bind the search field in IB in the desired way.
Do it like
1. Create an accessor-method (accessorMethodForTextInSearchField or what name you want to use) in the TopClass for the Text in the searchField
2. Import the TopClass.h in the MainClass
3. In MainClass you can use
NSString *searchString = [ NSString stringWithString:[ TopClass accessorMethodForTextInSearchField] ];
4. Now search for searchString in the array
I'm very new to objective-c and it seems my question is so basic there's nothing concise on it around (I just end up more confused by reading things).
When you create a .xib file, you link it to a controller (usually, I think). At the same time, you can do things you can do in .xib by defining views in code. I thought I understood part of it when I realized most of the items you drag onto a .xib are view objects. I guessed from there that .xib were somehow just representing real code for views. Is that accurate? Or am I completely wrong? I really have no idea.
Xib files do not represent real code for views, only the structure of the view's data. Each xib (or a storyboard) has enough information to do all of the following:
Instantiate elements of the view
Set properties of individual elements of the view
Connect elements of the view in a hierarchy
Connect "outlets" of objects in the Nib to properties or variables of views in your code.
However, there is no "real code" there, only the metadata. Cocoa has enough smarts to build and connect the objects, but the actual code is always in your .m files.
A view controller manages a view which is made up of many subviews. While, every view can have only one superview at most. ( superview is nil for the top-most view). This is called the view hierarchy.
The top level view in a hierarchy can be defined using pure code, or with Interface Builder, which produces a xib.
Its useful also to explore the relationship of view controllers to each other. Within one application window, there can also be several view controllers, each managing their own top-level view. This is called view-controller containment. An example of this is a UINavigationController or tab-bar controller. . .in more complex apps it is common to set up your own root controller that manages this aspect of controller heirarchies. (Eg swipe to reveal a navigation controller, which is under the main content cotroller).
A XIB describes arbitrary objects that conform to NSCoding but is usually used to layout a view hierarchy. So it'll be mostly UIViews, usually with a UIViewController.
However they're purely data. No code is generated. The system reads the XIBs and creates the objects purely as a data-reading exercise.
Objective-C has a fully reflective runtime — you can lookup classes by name as a string and can call methods on them the same way, without even knowing whether the method really exists in advance. Interface builders that secretly write code, such as Microsoft's in Visual C++, tend to do so because there's no way they could establish whatever you've described purely by parsing data.
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.
The issue i am facing deals with multiple views, each needing to communicate with one another. I chose to use the File Owner for this, but can't seem to be able to access the already loaded instance of it from inside of views.
Each rectangle represents its own view
Activity will happen on "Some View", where user's event will cause Labels in top view to be updated
Event will not be triggers by a button click of anything like that. No outputs are set up to establish relationships between the views
No outlets are set up between the views
Outlets are setup however between top Views (with Labels) and File Owner (UIViewController).
Ultimately, i'd like to update label in view 1 from view 2.
Then the bar moves, I want labels to change
At this time, i believe a reasonable solution would be to ask the File Owner to make a change for Labels. From the "Some View", i'd like to call the File Owner and make a request.
From the stand point of the any view residing as part of the nib, how can i know who the "File Owner" of this nib is?
In the Interface Builder, File Owner maintains the IBOutlet to UILabels of the view.
You need to define a delegate (or whatever you like to call it) outlet in your Puzzle1 class and link this to File's owner in the nib. This will give you a pointer to the instance of the view controller that currently owns your view. If you set the type of the delegate to your viewcontroller subclass, then its methods and properties will be available to you from within the view.
This sounds potentially horrendously messy and is probably better solved by using NSNotifications.
But anyways, did you know there's a UINib class? Perhaps you could subclass that and keep track of the owners (which get passed in it's instantiateWithOwner: options: method) as things are loaded.
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UINib_Ref/Reference/Reference.html
I have a document-based Core Data app. My main Core Data entity has several string fields, most of which are bound to NSTextFields, but one is bound to an NSTextView.
I am using the technique for view switching (with multiple view controllers) as explained in the Hillegass book. All of my subviews are controlled by a ManagedViewController, my subclass of NSViewController that has a managedObjectContext field.
My subview exists in a separate nib file. For some reason, the bindings I have set up in that nib are not working--but if I set up the widgets and the bindings in the exact same way in the main nib file instead, they work fine.
See image:
Screenshot http://img180.imageshack.us/img180/3391/screenshot.gif
In the main nib file, I have a tree controller whose managedObjectContext is bound to File's Owner's mOC (File's Owner is MyDocument). The NSTextField's value (yes, value--it's not rich text) is bound to treeController.selection.content (where content is a string property of the entity.) No problem. This works fine.
In the second nib file, I have another tree controller whose managedObjectContext is bound to File's Owner's mOC (File's Owner is my ManagedViewController). The NSTextField's value is bound the same way as above.
In my code, I have tested to make sure that the two managedObjectContexts refer to the same object. They do, and it's not nil.
I don't get an error--it's just that the values never bind with NSTextViews in the subview. They're always nil.
Also, I have tried NSTextFields--same problem.
Any ideas on how to make Core Data bindings play nicely with subviews and multiple NIBs?
You have two tree controllers. Each has its own knowledge of the selection. Try binding selectionIndexPaths from both of the tree controllers to a property of your document (you'll need to provide a way to get there through the view controller).