Cocoa touch - creating view template for iPad - objective-c

This is kinda a hard question to describe.
I'm just starting to make an iPad app.
Now with the amount of real estate I have, I'm planning to have different but similar "views" to populate the space. (might be easier to think a newspaper site, where many of the columns are similar)
I would like to create a "view template" so I can reuse the view in the different spots.
Is it possible to design the view template in Interface Builder? (meaning I design the UIView in Interface Builder and then somehow I can just do [window addSubview:viewController.viewTemplate1]; multiple times?
If so how would I load that view template in the different places?
If you know of an example code / tutorial that does something similar, that would work too.
Thanks,
Tee

Strictly speaking, UIViewControllers, as Laurent suggested, are only meant for views that take up the whole screen. From the View Controller Programming Guide:
The one-to-one correspondence between a view controller and a screen is a very important consideration in the design of your application. You should not use multiple custom view controllers to manage different portions of the same screen.
The correct technique here would be to use the NSBundle method -loadNibNamed:owner:options:, which instantiates the contents of a NIB and returns an array of the top-level objects. In this case, for each of your views, you'd do something like this:
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"MyViewTemplate" owner:nil options:nil];
UIView *newView = [nibObjects objectAtIndex:0];
[myViews addObject:newView];
// set up the view and add it to your content view and so on

The simplest way is to create a XIB file with:
- The view template you want.
- An UIViewController subclass, that will act as File Owner.
- Bind the UIView to the UIViewController subclass.
With this method (which is used widely in the Apple's samples), you can load as many as views you want and place them wherever you want.

Related

Using Xcode and Interface Builder to create prototype views

I'm building an NSView that is a kind of collection view, but instead of a table or a grid it will be a graph editor (similar to quartz composer).
The problem I'm facing now is that I would like to load prototype views (for the nodes) from a xib file. Much like how UITableView and UICollectionView lets you design prototype cells in Interface Builder. But how are these objects then instantiated in multiple copies?
How does UITableViewController et. al. achieve this?
Solutions I have thought about:
Copy the view, but NSView does not support NSCopying "out of the box". This seems like the most logical so far. It also seems like the only option if you want to keep the NSView in a storyboard rather than a xib.
Load a nib and then send [nib instantiateNibWithOwner:self topLevelObjects:nil] multiple times.
NSView does support NSCoding but using that feels more like a hack.
Any more ideas?
I'm developing an Mac OS X app, not an iOS app.
You are correct, implementing NSCopying via NSCoding does feel like a hack, but it's prob'ly the quickest and most reliable way to code it.
Copy NSView in cocoa / objective-c "related copy/code answer"
You can put your view in the storyboard as a top level object of any given scene. Make sure you have an outlet to it from the controller/loader of that scene. You could likely pack it into an NSData and just hold on to that for each "copy" you want made/unarchived.

What's the advantage of using UIViewController as owner of xib?

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

iOS, objective C - good example of application without XIB with MVC

I'm totally new with iOS development, having background with ActionScript3 with MVC. I love to code and I don't want to use any NIB/XIB files for my project (I've been told I will learn Objective C faster then) and I'm looking for a good example of iOS application using MVC pattern from scratch.
I know there is a bunch of good examples (like Good example code for Objective-C) but I haven't found any with no NIB/XIB usage.
Any ideas?
I'll try to give you some guidelines.
First of all. If you need some good tutorials, I suggest you to watch Brad Larson or Standford courses on iTunes. They are absolutely fantastic.
Then, if you want to create your MVC from scratch, I suggest you to take a look at UIViewController class reference.
Each UIViewController is a controller as the name suggest. The model could be contained in the controller itself (e.g. a NSArray) or provided by an "external" entity (e.g. Core Data). Each controller has a view property. The view is that element that is presented on screen. Usually could be provided by XIB or Storyboard files. As the apple documentation suggested:
If you cannot define your views in a storyboard or a nib file,
override the loadView method to manually instantiate a view hierarchy
and assign it to the view property.
In other words, within your view controller class you need to add this:
- (void)loadView
{
UIView* myCustomView = ...
self.view = myCustomView;
}
By means of this, you have a full control of the view presented on screen. This means that you need to provide the sizing and the positioning of the elements of your view. While a similar arrangement can be done by means of an user friendly interface in XIB or Storyboard files, you need to do it manually in other cases (e.g. deal with frame, autosizing mask, etc.).
Hope it helps.

How to bind nib custom view to a NSVIew subclass

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.

Custom UISplitViewController?

I want the effect of a UISplitViewController however I am not using the split view template.
Is it relatively easy to achieve without the template? And with using normal UIViewController?
What I want it a customary sized and positioned UITableView which then has a customary sized detail view which then of course goes into a popover and detail view when portrait.
Doing it without Interface Builder, you would create a UIViewController class. In the viewDidLoad method of that class, create a UIView or a UITableView with the frame origin where you want it and a size that you want. (Release it in the viewDidUnload method.) Then set the UIViewController's self.view to point to this new view.
self.view = [[UIView alloc] initWithFrame:...]; // edit - added in response to your question
If you created a UIView, then you will want to put your UITableView inside this new view. (This approach lets you add more items to the container UIView if you need to.)
Make sure your UIViewController adheres to the UITableViewDelegate and UITableViewDataSource protocols. Add the delegate and datasource methods and you should be good to go.
This new view can cover other views, or you can size the other views to fit beside it. You only need to set there frames according to what you want to do with them.
There are some limitations if you use a UITableViewController, so a lot of people recommend using a UIViewController instead. like I described above. You can google for more info on that topic.
Just great a new temporary Xcode-project from that template and judge yourself, if it is complicated for you, to adept your (real) code.
Yes. You can do it quite easily. Just use delegates to pass messages between the left and the right side views (root and detail). For instance the didSelectRowAtIndexPath tableView method could be used along with delegation to pass a message to the right sided detail view. Tap a cell on the left table, show its text as a Label on the right side. Its just a simple example. And yes you can handle the rotations and send left side view into a UIPopoverController as well, thus giving the detail view full screen real estate in Portrait orientation.
Also try MGSplitViewController . It gives you a lot of other customization options on a split view controller.