Can I load nib contents in to UIView using only Interface Builder? - objective-c

Does anyone know a way to, in a storyboard, load a UIView's contents from another nib? I know I can do this easily with code, but I am trying to figure out how to do more in IB.
I have a storyboard with my main UI layout, I have a UIScrollView and I want to design its contents in IB. The only way I could figure out how to do this was to design the UIView in its own .nib, but then my issue is, how do I load the nib without coding it to do so? Is this even possible? It doesn't seem too far fetched to me.

I'm assuming you simply want to lay out your UIScrollView in IB, that a .nib is mentioned because that was an approach you were exploring, but if you could do this strictly in your storyboard that would be acceptable, if not preferable:
First, create a new file in Xcode that is a subclass of UIScrollView.
In your storyboard, drag a UIScrollView out to the scene (viewcontroller) where you want to display this scroll view.
In the Identity inspector, set the Custom Class of the UIScrollView to your subclass of UIScrollView.
Create an outlet for this UIScrollView by ctrl+dragging the UIScrollView into the .h file of the ViewController subclass it's displayed in. Name it something like myScrollView
In your ViewController's -viewDidLoad method, set the contentSize property of the UIScrollView to whatever size you want it to be. So it will look something like:
self.myScrollView.contentSize = CGSizeMake(800,800);
Now, drag out UI objects to your UIScrollView and design.
IMPORTANT: To create outlets to these objects is a little tricky. Let's say you've dragged out a UILabel. You need to manually go into your UIScrollView subclass and add to the .h
#property (nonatomic, weak) IBOutlet UILabel* myLabel;
and to the .m
#synthesize myLabel = _myLabel;
Now you need to get your outline view on screen along with your storyboard and ctrl+drag FROM YOUR SCROLL VIEW TO YOUR LABEL to create an outlet. This is kind of the reverse of what you're used to.
Now you can reference that outlet from within the viewcontroller or the scrollview subclass . For instance, in the viewcontroller -viewDidLoad you could say:
self.scrollView.myLabel.text = #"Hello World";
HTH!

If what you want is to edit inside a scrollview from IB, it's a pain, but doable.
Have a look at my answer on this question.

Add a generic UIView in the IB, setting its custom class to the name of your nib file.
Replace GradientControl with the name of your nib file (minus the '.xib').

Related

Custom view from NSWindowController Cocoa

I have an application with two windows, the main window opens the second window that is a NSWindowController and in its xib file there is a custom view, is there any way to draw in this custom view from NSWindowController?
thanks
Override - (void) drawRect:(NSRect) dirtyRect in your custom NSView to do the drawing.
If you need to inform this drawRect method from your (custom) NSWindowController, you can use delegate or data source patterns by setting an outlet from the view to the NSWindowController.
solved, I have declared two IBOutlets, one on NSView:
IBOutlet MyNSWindowController *wc;
and one on NSWindowController:
IBOutlet MyNSView *view;
then, I have to connected them to custom view.
Now I can to use its methods simply calling its IBOutlets.

Why I can't drag outlets from a custom UIView Class?

I have a TableViewController With a dynamic cell and a view I added above it.
I've created a UIView class and added it as a custom class for that view ( just like I do with a custom cell) but I can't drag labels etc from that UIView to its .h file. Only to the main TableViewController.h file. Any idea what's the problem?
A table view in a UITableViewController takes up the whole screen, so the view you added is actually in the table view, not above it, so that's why you can connect to the table view controller. If you want to add a view above the table, use a UIViewController instead, and resize the table view so it doesn't take up the whole screen.
I've noticed this too (for an OS X project) in Interface Builder. I'm not sure if it is a bug or not in IB.
What you will have to do is enter the #property declarations in your .h file manually and then you will be able to connect them.

Redrawing an NSView

Sorry if this has been asked before or it's a really dumb question, but I can't figure it out. I have an NSView in my interface, and I have created a subclass of NSView in Xcode. Then using the identity inspector, I set my NSView's class to be the newly created NSView subclass. The view draws fine, but now I need to redraw it to change a string inside the view. I'm pretty sure this has to do with setNeedsDisplay, but what do I send the message to? I don't have a particular instance of my view in the code, since it's in Interface Builder, so what do I do?
Again, sorry if this is dumb. I haven't done much with NSView yet. Ask for more info if you need it. Thanks!
In the view controller subclass you have, add an ivar with type of your NSView subclass. Declare a property on it, and mark it as an outlet.
// ViewControllerSubclass.h
ViewType *myView;
#property(readwrite, assign) IBOutlet ViewType *myView;
// ViewControllerSubclass.m
#synthesize myView;
Now you have an outlet, connect it to the view you designed via IB. To do so, right click in IB on your view controller subclass (the file's owner), you should see the outlet in the list.
Once you have done that, you are now able to send messages to the view in your code.
To mark the view as needing redraw :
[myView setNeedsDisplay:YES];

Associating a UITableView with a TableViewController

Can anyone describe how it is possible to have a TableViewController with its xib file having a at its root and the uitableview as a subview?
I believe the TVController somehow assumes that UITableView will fill the entire area.
Why is that?
I have a really specific need to build a kind of side and bottom tabbed interface with a UITableView as its main area. Pressing tabs changes the predicate for the fetchedresultscontroller etc etc.
The reason I want this is because of the breadth and depth of the data categories in the data model. I rally need to flatten the menu structure a lot...other wise with a table and navbar controller structure, user experience will be akin to sinking to ever deeper depths of a cavern!
My idea is tried and true in other paradigms...in iOS it almost looks like it's Apple's way or the highway. I am OK with APPLE of course no gripe.
But I really would like to create this.
I tried adding a new tableviewcontroller complete with xib and then removing the UITableView in IB and replacing with a UIView and a UITableView as a subview, hooking up (I believe) the delegate to the file's owner.
I created an IV tableView for when I want to reference it and again used IB to hook it up in IB
Try to run it and it whines that...
[UITableViewController loadView] loaded the "TabbedTableController" nib but didn't get a UITableView.'
Really can't seem to get my head around what the issue is here.
There doesn't appear to be anymore I can do to hook the UITableView up!
Any help would be terrific. I'll send you a Christmas card in desperation :^)
Also...why should it be so and how strict is this UITableView fullscreen thing?
Enlighten me if you can. The docs I have read don't want to.
Regards
Keith
A UITableViewController does assume that the root view (i.e. the controller's view property) will be a UITableView, thus the table view fills the screen. When you need a view that combines UITableView with other top level views, you will need to do a little more work but it's not hard:
Your view controller will not subclass UITableView. Instead, do this:
#interface MyViewController : UIViewController
<UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, weak) IBOutlet UITableView* tableView;
In Interface Builder, drop in a UITableView and whatever other controls you need. The table view can be any size and in any location in the view hierarchy. Also in Interface Builder, ctrl-drag from the table view to your VC and set the delegate and dataSource outlets, and ctrl-drag from your VC to the table view to set the tableView outlet.
Your view controller implementation should be the typical table view controller implementation: cellForRowAtIndexPath, etc.
A UITableViewController is more or less just all of the above work packaged up into a single unit for you.

iPhone: Accessing view objects from a ViewController in Code

Let's say I have a ViewController that needs access to a view. In the class file of the ViewController I am doing
IBOutlet ViewA *someview;
And in Interface Builder, I drag and drop a UIView in my document and set the class to ViewA.
I am missing how "stuff" is instantiated when you connect through IB. Is ViewA automatically allocated when the .xib files are unarchived? What if I don't want to use IB?
If you don't want to use IB, instead of putting that IBOutlet there, you just eliminate it, leaving just
ViewA *someview;
and then somewhere in your code, when you need the view, you do a
someView = [[UIView alloc] initWithFrame: rect];
I prefer IB, others prefer programmatically creating views. I like how I can position all the views subViews, including UIButtons, UILabels, UITableViews, other UIViews, etc. without having to use coordinates to do so. YMMV.
As to when things get instantiated, when using a XIB, your app will probably lazily load the view controller, and once it is loaded, it will load your view. What actually loads your view, is when you first access the variable someView. While there is an outlet connection, the view and its subViews are not loaded till you access someView, in any manner, for example if you just do a:
if (someview) {
// the view is loaded now
}