views:

474

answers:

2

Okay I just typed this whole question out and then managed to delete it. Sigh. Anyway, standard disclosure that I have searched everywhere and banged my head on the keyboard and can't figure this out.

I'm building a basic app based on the utility application template (with a MainViewController and FlipsideViewController). Side note: I still don't understand the purpose of MainView and FlipsideView in this scheme so if someone can explain it that wouldn't be too terrible :D

Anyway, at the bottom of both of these views I want to have a toolbar. It was easy enough to add that to a given view with IB, but I want the toolbar to have its own controller and model because I want to keep its state consistent across the two views. Accordingly I'd like to load that view from a nib but it seems I'm doing something wrong. I followed the advice here: http://stackoverflow.com/questions/1726250/nsviewcontroller-and-multiple-subviews-from-a-nib but obviously borked it up so more insight would be appreciated.

I did the following things: I created ToolBarViewController which is basically empty but is the file owner of ToolBar.xib. Inside ToolBar.xib I have a view with a frame the size of the toolbar and inside that a toolbar. In MainView.xib I've got a view element of the same size which is wired up to toolBarView found in the code below...

In MainViewController.h:

#import "ToolBarViewController.h"

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate, MKMapViewDelegate> {
 ...
 ToolBarViewController *toolBarViewController;
 IBOutlet UIView *toolBarView;
}

...
@property(nonatomic, retain) ToolBarViewController *toolBarViewController;
@property(nonatomic, retain) IBOutlet UIView *toolBarView;

In MainViewController.m:

@synthesize toolBarViewController;
@synthesize toolBarView;

- (void)loadView
{
    [super loadView];
    toolBarViewController = [[ToolBarViewController alloc] initWithNibName:@"ToolBar" bundle:nil];
    [[toolBarViewController view] setFrame:[toolBarView frame]];
    [[self view] replaceSubview:toolBarView with:[toolBarViewController view]];
}

When I build and run I get the warning for the last line above that 'UIView' may not respond to 'replaceSubview:with' and on running it the following exception is thrown: * -[MainView replaceSubview:with:]: unrecognized selector sent to instance 0x450c540

Can anyone explain what I'm doing wrong? Thanks!å

A: 

That's because there's no such UIView's replaceSubview:with: (there's a method like that for NSView on the Mac, though).

Remember that Objective-C warnings are usually errors ;) in general I tend to never leave them without treatment, and I even turn them into errors: http://akosma.com/2009/07/16/objective-c-compiler-warnings/

Adrian Kosmaczewski
A: 

There is no such method as [UIView replaceSubview:with:]. That's an NSView method. You should have gotten a warning about this when you compiled.

To do the same thing, you'd need to use [[self view] insertSubview:aboveSubview:] and then [toolbarView removeFromSuperview].

That said, I'm not certain if this is how you want to mess with the toolbar. I'd probably try something more like:

self.toolbarItems = [toolbarViewController toolbarItems];
Rob Napier
Ah okay, I didn't realize the info was about NSView not UIView - too much head bashing against the keyboard :DIn any case, what would toolBarItems be in this case? I feel like what I'm doing is starting to look hacky but there should be a straightforward way to load a nib into another. That's what apple recommends no? I just can't find a clear example of how to do it...
deadroxy
Okay instead I tried the addSubView method like so:toolBarViewController = [[ToolBarViewController alloc] initWithNibName:@"ToolBar" bundle:nil];[[toolBarViewController view] setFrame:[toolBarView frame]];[[self view] addSubview:[toolBarViewController view]];And that seemed to work. Thanks for putting me on the right track, now let's see if it goes forward more smoothly!
deadroxy
toolbarItems is a property of the UIViewController, and is what's used to create the toolbar. You are using a real toolbar here, right? I mean a list of UIBarButtonItems that UIViewController manages for you, as described here as the Navigation Toolbar: http://developer.apple.com/iPhone/library/featuredarticles/ViewControllerPGforiPhoneOS/NavigationControllers/NavigationControllers.html. Or is this just a "normal" view that you want to reuse?
Rob Napier
It's basically a toolbar element with a slider and two buttons inside. So the method I described above - creating a nib and corresponding controller and then using addSubview is not good? I'm going for something like what you see in the apple templates like this area is "loaded from controller x."
deadroxy
Usually addSubview from a second view controller would be fine, but this is replacing your toolbar, which is managed by the UINavigationController. If these are toolbar elements (UIBarButtonItem), then I'd just put them into your UIVIewController's toolbarItems rather than blow away the whole toolbar view. That way the UINavigationController can properly manage the toolbar like it expects to. Take a look in the docs at the "toolbarItems" property of UIViewController and the above link about the Navigation toolbar.
Rob Napier
Ahh I understand, the view itself isn't managed by a UINavigationController but rather a UIViewController with a map (it's the front side of a flipside view). The backside is a navigation controller but I was just using the toolbar element directly rather than via a navigation controller as on the front side it doesn't have one. Just to be clear, I'm talking about the tool bar at the bottom not the nav bar at the top. But maybe I'm missing something about best practices here. Basically I want a controller which manages the events coming off the slider in the toolbar.
deadroxy
If this view isn't in a NavigationController, then inserting the view with addSubview may be fine.
Rob Napier