Complicated Design Question Regarding iOS App
So I have an interesting design question regarding an app I'm developing for the iPhone. I am creating an app that manipulates images, and there are different types of manipulations that can be performed. So the user opens the app, and selects what type of manipulation they want to perform, and are taken through a step by step process to perform the manipulation.
A lot of the manipulations are similar, so code can be reused here. So instead of creating a view controller for each window of each manipulation, I decided to create one view and one view controller. The view contains the steps of each image manipulation, and each time it is incremented to the next step, it reorganizes itself appropriately. The view controller is controlled by a navigation controller, and each time the user advances to the next step of whatever image manipulation they're trying to perform (ie pushed a new view controller on the stack), I make a copy of my view object, set it to reorganize its components to the appropriate step, then send it to the new view controller which will display it.
So my question is this, for some stages of the manipulations, I need to add some buttons to a universal toolbar that is attached to view controller 开发者_如何学Go(since this is a modal view, this tool bar will have a home button that will enable the user to exit back to the main screen). Basically, I have a couple of questions on how I should approach this:
1) Should I simply add the toolbar to the view that I'm using, instead of the view controller. If so, how would I have the home button on the toolbar exit the modal view?
2) Should I keep the toolbar on the view controller, and have my view return a set of buttons to be added to it when the view loads? Then I guess I would have to list all of my action methods in my view controller?
3) Should I keep the toolbar on the view controller, but send a pointer from the toolbar to my view object, then add the buttons within my view class? Would I be able to add my action methods in my view class then?
Anyhow, sorry if this is complicated, and if you have any follow up questions please let me know.
1) Ok.
For dismissing, does your view have a pointer to the view controller? How about something like this:
[self.viewController.parentViewController dismissModalViewControllerAnimated:YES];
Not sure if I understand exactly how your hierarchy is organized. That's just my guess.
2) That seems kludgy to me. You'd have to define some sort of data structure that describes what the view wants in a button, make a list of them. The view controller has to request that list, go through them.
3) That seems like the best option. But I wouldn't have your view directly add subviews to the toolbar. Create a ToolbarView custom view. Give it some kind of addButton method, with parameters that describe what essential attributes you want the button to have, like title and the target and action maybe. Let the ToolbarView decide what it looks like, where it's positioned, etc.
Can your action methods go on your view class? Yeah I guess, but they shouldn't. The recommended iPhone design pattern is that views shouldn't do anything, they should just show things. Methods that do things should be on view controllers, even if the only thing they do is change what views are being shown.
I finally came up with a solution for this. What I did was create a universal view controller called UIMainViewController that obviously inherits from UIViewController. I implement the toolbar like follows:
- (void) viewDidLoad
{
[super viewDidLoad];
[self assembleToolbarButtons];
[[self navigationController] setToolbarHidden:NO];
[self setToolbarItems: toolbarButtons];
[[[self navigationController] toolbar]setBarStyle:UIBarStyleBlack];
}
- (void) assembleToolbarButtons
{
NSMutableArray *toolbarButtonsTemp = [[NSMutableArray alloc] init];
[self setToolbarButtons: toolbarButtonsTemp];
[toolbarButtonsTemp release];
if ([self mode] == UIMainViewControllerMainMode)
{
UIBarButtonItem *createAPictureButton = [[UIBarButtonItem alloc] initWithTitle:@"Create" style: UIBarButtonItemStyleBordered target:self action:@selector(loadCreateAPictureModalViewController)];
UIBarButtonItem *accountButton = [[UIBarButtonItem alloc] initWithTitle:@"Account" style: UIBarButtonItemStyleBordered target:self action:@selector(loadAccountModalViewController)];
UIBarButtonItem *helpButton = [[UIBarButtonItem alloc] initWithTitle:@"Help" style: UIBarButtonItemStyleBordered target:self action:@selector(loadHelpModalViewController)];
[[self toolbarButtons] addObject: createAPictureButton];
[[self toolbarButtons] addObject: accountButton];
[[self toolbarButtons] addObject: helpButton];
[createACaptionButton release];
[accountButton release];
[helpButton release];
}
else
{
UIBarButtonItem *homeButton = [[UIBarButtonItem alloc] initWithTitle:@"Home" style: UIBarButtonItemStyleBordered target:self action:@selector(exitModalViewController)];
[[self toolbarButtons] addObject: homeButton];
[homeButton release];
}
}
-(void) loadCreateAPictureModalViewController
{
CreateAPictureViewController *createAPictureViewController = [[CreateAPictureViewController alloc] initWithMode:UIMainTableViewControllerModeModal];
UINavigationController *createAPictureNavController = [[UINavigationController alloc] initWithRootViewController: createAPictureViewController];
[[createAPictureNavController navigationBar] setBarStyle:UIBarStyleBlack];
[self presentModalViewController:createAPictureNavController animated:YES];
[createAPictureNavController release];
[createAPictureViewController release];
}
-(void) loadAccountModalViewController
{
AccountViewController *accountViewController = [[AccountViewController alloc] initWithMode:UICaptionDistractionTableViewControllerModeModal];
UINavigationController *accountNavController = [[UINavigationController alloc] initWithRootViewController: accountViewController];
[[accountNavController navigationBar] setBarStyle:UIBarStyleBlack];
[self presentModalViewController: accountNavController animated:YES];
[accountNavController release];
[accountViewController release];
}
-(void) loadHelpModalViewController
{
HelpViewController *helpViewController = [[HelpViewController alloc] initWithMode:UICaptionDistractionTableViewControllerModeModal];
UINavigationController *helpNavController = [[UINavigationController alloc] initWithRootViewController: helpViewController];
[[helpNavController navigationBar] setBarStyle:UIBarStyleBlack];
[self presentModalViewController: helpNavController animated:YES];
[helpNavController release];
[helpViewController release];
}
-(void) exitModalViewController
{
[self dismissModalViewControllerAnimated:YES];
}
So for my app, on each viewcontroller it will have a toolbar at the bottom that have the basic buttons for creating a picture, accessing the account, or accessing help. If one of these buttons is accessed, it will launch a modal view which will have the home button to exit the modal view (when the UIMainViewController is created, one of it's parameters tells it which mode it is in, and thus which toolbar buttons to add.
But the main thing is I created a class mutablearray varialbe to store the toolbar buttons and then the buttons are created in "assembleToolbarButtons". Now any class that inherits from UIMainViewController can override the assembleToolbarButtons in order to add it's own buttons on top of the main ones that have already been added.
As far as what I mentioned initially in using one UIView and having it reorganize itself, and only one uiviewcontroller, I avoided this and instead just created separate view controllers for each step and separate views so as to adhere to MVC more.
精彩评论