开发者

iOS custom navigation with nested view controllers

I am not exactly sure the best practice of doing this, so I thought I'd ask.

Here's the program's objective:

  • A custom navigation controller created via a root UIViewController that does not actually subclass UINavigationController(To easily manipulate the design)
  • Nested view controllers for different screens (manipulated by the main view controller)
  • Ea开发者_StackOverflow中文版ch nested view controller has its own nib file

Currently, I have it working, however each nested view controller is not a view controller but a subclassed UIView. I feel like this is bad practice because I am using these UIViews in a view controller way but without the functions of a view controller (ie. viewDidLoad). Also, these UIViews are taking on the usual delegate methods of a UIViewController (which really sets off red flags).

Is this actually bad practice?

Things I am afraid of when trying to switch to UIViewControllers are that I would still have to make a subclass of UIView to identify which view to point to when I load the nib via:

NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil];

for (id object in bundle) {
    if ([object isKindOfClass:[SubclassedUIView class]])
        currentScreenViewController = (SubclassedUIView *)object;
}

I haven't checked yet, but I assume I have to do "SubclassedUIView" rather than just UIView in that statement because there are other UIView objects in the bundle. But then again, that situation may be better off than the current one.

A different solution may be to make MainViewController a delegate for all of the UIViews that require a delegate and create categories of the MainViewController containing the delegate methods for each nested nib.

Any idea here?


Create a UIViewController subclass for each SubclassedUIView type, ticking the option to create a XIB file for the interface, and move all of the code over to that, pointing it to self.view. Then open up Interface Builder with the .xib for that view controller and configure the visual appearance of the UIView as much as you like. To manipulate visual elements from the main view controller you will have to either assign "Tag" numbers to each element or create a whole bunch of IBOutlet instance variables and hook them up to your elements in IB. The way you present view controllers properly using a UINavigationController is:

/* at the top of your main view controller */
#import "SubclassedUIViewController.h"

/* when navigating to the next view */
SubclassedUIViewController *newController = [[SubclassedUIViewController alloc] initWithNibName:@"SubclassedUIViewController" bundle:nil];
[(UILabel *)[newController.view viewWithTag:6] setText:@"Text"]; // example of accessing elements using tags
[newController.textLabel setText:@"Text 2"]; // example of accessing elements using IBOutlet connections
[self.navigationController pushViewController:newController animated:YES];
[newController release];

Interface Builder also allows you to add the navigation controller to your main view controller .xib file and provide the back button text, main title, etc. When you implement your subclassed view controllers, override initWithNibName:bundle: and set self.navigationItem.title and any other properties of self.navigationItem you want.

EDIT: Did you mean you have to be able to manipulate specific properties of some of the subclassed views while in other ones? As in, you require access to all of them all the time? If this is the case then make connections to your subclassed views upon loading the main view controller, that is:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.subclassedController1 = [[SubclassedUIViewController1 alloc] initWithNibName:@"SubclassedUIViewController1" bundle:nil];
    // self.subclassedController2 = ... etc
}

/* in your loading next view code you can skip the alloc/init line */
[self.navigationController presentViewController:subclassedController2 animated:YES];

And then in your subclassed controllers you can get to the main controller in a few ways:

  1. A call to self.parentViewController
  2. A call to [(MyCustomAppDelegateClass *)[[NSApplication sharedApplication] delegate] rootView] or similar (basically, the reference your application delegate holds to the main view of the application).
  3. By adding an @property (assign) property and ivar to the subclassed controller pointing to the main view controller. You can assign this on loading your main view controller with subclassedController1.mainViewController = self.

Helpful docs:

  1. View Controller Programming Guide for iOS: Navigation Controllers
  2. Xcode Quick Start Guide (updated for Xcode 4)


Apparently, what I was doing was sort of OK according to How to add an UIViewController's view as subview.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜