I want to have a View which contains more than one view. see the below image:
as you see pageController controls page navigation and provide before and after viewController (page).
pageContentController displays text and process them.
soundPlayer manages playing related sound
I can have all of them in one controller, but my controller must do a lot of tasks and managing it will be hard task. as it disobey light view controller. and decrease its cohesion. so I wanted to know how can I accomplish this please explain in details.
thanks for your detailed answers. your answers clarified me. what I did:
I added SoundPalyerVC
as child of PageContentVC
SoundPlayerVC *soundPlayer = [[StoryViewController alloc] initWithStory:self.storyManagedObject];
[self addChildViewController:soundPlayer];
[self.view addSubview:soundPlayer.view];
[soundPlayer didMoveToParentViewController:self];
soundPlayer.view.frame = CGRectMake(0, self.view.frame.size.height-soundPlayer.view.frame.size.height, 320, soundPlayer.view.frame.size.height);
that was so easy. now my codes are separated.
What I would do is:
1) Create custom classes for each view.
2) Then I would set the View Classes to the classes that I created.
3) Then I would write the code to handle whatever functionality you need within these view classes.
@interface PageContent : UIView
- (void) showTest : (NSString *) textToShow;
@end
@implementation PageContent
- (void) showTest : (NSString *) textToShow
{
//Then here you would do whatever you need to do with this text, and display it
}
@end
@interface SoundPlayer : UIView
- (void) playSound;
@end
@implementation SoundPlayer
-(void) playSound
{
//Do whatever you need to do with the sound here.
}
@end
4) Then create outlets to each one of these views in your View Controller Class.
//So your View Controller Class would look something like this.
@interface YourViewController : UIViewController
@property (strong, nonatomic) IBOutlet Page *page;
@property (strong, nonatomic) IBOutlet PageContent *pageContent;
@property (strong, nonatomic) IBOutlet SoundPlayer *soundPlayer;
@end
5) Then in your View Controller @implementation you could do stuff like
@implementation YourViewController
-(void) showContent
{
[self.pageContent showText:@"Text To Show"];
}
-(void) playSound
{
[self.soundPlayer playSound];
}
@end
Now when you call these ([self showContent] or [self playSound]) methods in the view controller, it will call the methods for the specific views, so that way you don't have an extremely long non reusable view controller.
I just showed a view examples, I hope that you can see what I'm doing here, and implement this for everything that you need.
To your pageController view, add pageContentController's view and soundPlayer's view as subview to it.
write below code in pageController.m file
soundPlayer = [[SoundPlayer alloc] init];
[self.view addSubview:soundPlayer.view];
souldPlayer.frame = //set it value as desired.
Similary the pageContentController.
Starting in iOS 5, Apple added parent/child view controller support to the OS. There are new calls in the UIViewController class to support setting up parent/child view controller relationships, where one view controller (the parent) sets up or ore more other view controllers so that their content views are inserted into the view hierarchy of the parent. This was a major improvement, but a fair amount of work to set up correctly and make everything work right.
Starting in iOS 6, Apple added container views (which is just a UIView with a special type) and embed segues. What you do is open up the scene of the view controller that's going to be the parent in IB, select the list of interface objects, and type "container". You should see a container view. Drag a container view onto your parent view controller and place it where you want it.
Then control-drag from your container view to the scene that defines the interface of the child view controller you want to place in that container. It should default to creating an embed segue. Accept the default. That's pretty much it. Now, when you load the parent view controller, the system will also instantiate any child view controllers that you have set up and wire up all the "plumbing" that makes it work correctly.
If you need the parent and child to communicate you can set an identifier on your embed segue and then write prepareForSegue code that configures the child, just like any other segue.
Container views and embed segues are WONDERFUL, and make setting up this sort of thing really easy.
I have a sample project on github that uses embed segues to good effect. Here's the link:
Demo project using embed segues to manage 2 static table views in a parent VC.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With