Zodat u een idee krijgt van hoe de weergave van controllersystemen eruit kan zien (iOS 5), dit is een manier om het te doen. Het bestaat uit vier klassen, de container view-controller (wiens weergave de gesegmenteerde besturing heeft voor het schakelen tussen twee child view-controllers), twee willekeurige child view-controllers en een modelklasse waarin we de gegevens opslaan (waartoe toegang kan worden verkregen door de twee child view controllers).
Eerst maak je een containerzichtcontroller met je gesegmenteerde besturingselement (ik heb ook een UIView toegevoegd die in feite het frame definieert waar de weergaven van child view controllers worden geplaatst, gewoon om het gemakkelijker te maken om uit te zoeken waar die weergave moet worden geplaatst):
// ContainerViewController.h
#import
@interface ContainerViewController : UIViewController
@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentedControl;
@property (weak, nonatomic) IBOutlet UIView *childView;
- (IBAction)changeChild:(id)sender;
@end
En dan implementeer je het:
// ContainerViewController.m
#import "ContainerViewController.h"
#import "FirstContainedViewController.h"
#import "SecondContainedViewController.h"
#import "MyModel.h"
@interface ContainerViewController ()
{
FirstContainedViewController *_controller0;
SecondContainedViewController *_controller1;
MyModel *_model;
UIViewController __weak *_currentChildController;//let's keep track of the current
}
@end
@implementation ContainerViewController
@synthesize segmentedControl = _segmentedControl;
@synthesize childView = _childView;
- (void)dealloc
{
//let's release our child controllers
_controller0 = nil;
_controller1 = nil;
//and release the model, too
_model = nil;
}
// this is my own method to
// 1. add the child view controller to the view controller hierarchy;
// 2. do the appropriate notification (even though I don't use it, Apple says you should do this, so I will); and
// 3. set the frame size to the appropriate size
- (void)addChildToThisContainerViewController:(UIViewController *)childController
{
[self addChildViewController:childController];
[childController didMoveToParentViewController:self];
childController.view.frame = CGRectMake(0.0,
0.0,
self.childView.frame.size.width,
self.childView.frame.size.height);
}
- (void)viewDidLoad
{
[super viewDidLoad];
//let's create our model, our data
_model = [[MyModel alloc] init];
//set the segmented index to point to the first one
[self.segmentedControl setSelectedSegmentIndex:0];
//let's create our two controllers and provide each a pointer to our model
_controller0 = [[FirstContainedViewController alloc] initWithNibName:@"FirstContainedView" bundle:nil];
_controller0.model = _model;
_controller1 = [[SecondContainedViewController alloc] initWithNibName:@"SecondContainedView" bundle:nil];
_controller1.model = _model;
//let's add them to the view controller hierarchy
[self addChildToThisContainerViewController:_controller0];
[self addChildToThisContainerViewController:_controller1];
//let's add the currently selected controller as the "current child controller" and add it to our current view
_currentChildController = [self.childViewControllers objectAtIndex:self.segmentedControl.selectedSegmentIndex];
[self.childView addSubview:_currentChildController.view];
}
- (void)viewDidUnload
{
[self setChildView:nil];
[self setSegmentedControl:nil];
[super viewDidUnload];
//Release any retained subviews of the main view.
}
- (IBAction)segmentedControlValueChanged:(UISegmentedControl *)sender
{
UIViewController *oldChildController = _currentChildController;
UIViewController *newChildController = [self.childViewControllers objectAtIndex:sender.selectedSegmentIndex];
UIViewAnimationOptions options;
//let's change the animation based upon which segmented control you select ... you may change this as fits your desired UI
if (sender.selectedSegmentIndex == 0)
options = UIViewAnimationOptionTransitionFlipFromLeft;
else
options = UIViewAnimationOptionTransitionFlipFromRight;
[self transitionFromViewController:oldChildController
toViewController:newChildController
duration:0.5
options:options
animations:nil
completion:nil];
_currentChildController = newChildController;
}
@end
Mijn model heeft slechts twee gegevenselementen, een reeks objecten en een tekenreeks, maar u kunt natuurlijk doen wat u wilt. Ik laat alleen de koptekst zien (omdat de implementatiedetails triviaal en oninteressant zijn):
// MyModel.h
#import
@interface MyModel : NSObject
@property (nonatomic, strong) NSMutableArray *listOfItems;
@property (nonatomic, strong) NSString *displayText;
- (MyModel *)init;
@end
En de controllers voor kindweergave zijn ook triviaal:
// FirstContainedViewController.h
#import
@class MyModel;
@interface FirstContainedViewController : UIViewController
@property (nonatomic, weak) MyModel *model;
@end
En de implementatie kan er ongeveer zo uitzien (dit is een triviaal voorbeeld, maar laat zien hoe u informatie van het gedeelde model kunt ophalen):
// FirstContainedViewController.m
#import "FirstContainedViewController.h"
#import "MyModel.h"
@implementation FirstContainedViewController
@synthesize model = _model;
- (void)viewDidLoad
{
[super viewDidLoad];
//Do any additional setup after loading the view.
}
- (void)viewDidUnload
{
[super viewDidUnload];
//Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - tableview data source delegate methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.model.listOfItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"fcvc";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.textLabel.text = [self.model.listOfItems objectAtIndex:indexPath.row];
return cell;
}
@end
Hopelijk geeft dit u een idee van hoe u afzonderlijke view controllers voor uw twee weergaven zou kunnen gebruiken, hoe u ertussen kunt schakelen, uw model toegankelijk maken voor beide. Dit is een vrij eenvoudig voorbeeld, maar het is functioneel. Er zijn enkele optimalisaties die ik zou kunnen voorstellen, maar hopelijk is dit voldoende om u in de goede richting te laten gaan.