I am implementing a UIViewController with ScrollView. In the centre of the view I have a ToolBar like that one in the picture:
I have four UIViewControllers to add, one for each button of the toolBar. I do not know if I should init all off them at the beginning and then with a NSArray of viewControllers and one NSArray of booleans manage all of them with this methods:
How could I manage this?? Change viewControllers at the bottom of the toolBar while any button is pressed
- (void) displayContentController: (UIViewController*) content;
{
scrollView.contentSize =CGSizeMake(scrollView.frame.size.width, self.view.frame.size.height + content.view.frame.size.height );
[self addChildViewController:content];
content.view.frame = [self frameForContentController];
[scrollView addSubview:content.view];
[content didMoveToParentViewController:self];
}
- (void) hideContentController: (UIViewController*) content
{
[content willMoveToParentViewController:nil]; // 1
[content.view removeFromSuperview]; // 2
[content removeFromParentViewController]; // 3
}
I have never used childViewControllers actually and I really do not know how to use them
You want to essentially create your own TabBarcontroller. You should use child view controller otherwise auto rotation will not work as expected. You should use an array of ViewControllers (required to pass data) and delegates when your interact with your tabBar. Here is an excellent example which does the same.MHTabBarController.
Here is a sample interface for it:
#interface MHTabBarController : UIViewController
#property (nonatomic, copy) NSArray *viewControllers;
#property (nonatomic, weak) UIViewController *selectedViewController;
#property (nonatomic, assign) NSUInteger selectedIndex;
#property (nonatomic, weak) id delegate;
- (void)setSelectedIndex:(NSUInteger)index animated:(BOOL)animated;
- (void)setSelectedViewController:(UIViewController *)viewController animated:(BOOL)animated;
#end
Related
I had a UIViewController and a UIContainer View.
I want to simulate the UIAlertView effect, But I don't know how to build the Container View show and hide about the great method.
I had put the UITableView in my UIContainer View, I use delegate to send selected item to the UIViewController(ParentViewController) and show in the label.( segue name with alertSegue)
There have a show button in the ParentViewController,and I need click the selected item ,it will close(hide/dismiss?) the UIContainer View.
Now UIContainer View default is hidden,and storybaord screen shot like below:
My ParentViewController.h
#interface ViewController : UIViewController<ContainerViewBLETableDelegate>
#property (weak, nonatomic) IBOutlet UIButton *btn;
- (IBAction)btnAction:(id)sender;
#property (weak, nonatomic) IBOutlet UILabel *lb;
#property (weak, nonatomic) IBOutlet UIView *containerView;
-(IBAction)unwindSegue:(UIStoryboardSegue *)segue;
#end
.m file:
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)btnAction:(id)sender {
_containerView.hidden = NO;
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:#"alertSegue"])
{
ContainerViewBLETable *vc = segue.destinationViewController;
vc.delegate = self;
}
}
-(void) ContainerViewBLETable:(ContainerViewBLETable *)vc andSelectedDone:(NSString *)selectedStr
{
self.lb.text = selectedStr;
vc.view.hidden = YES;
}
-(IBAction)unwindSegue:(UIStoryboardSegue *)segue
{
}
Container ViewController .h :
#class ContainerViewBLETable;
#protocol ContainerViewBLETableDelegate <NSObject>
-(void) ContainerViewBLETable:(ContainerViewBLETable*)vc andSelectedDone:(NSString*)selectedStr;
#end
#interface ContainerViewBLETable : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property(nonatomic,assign) id<ContainerViewBLETableDelegate>delegate;
#property (weak, nonatomic) IBOutlet UITableView *tableVW;
#end
UIContainerView .m part:
.....
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate ContainerViewBLETable:self andSelectedDone:[NSString stringWithFormat:#"%ld",indexPath.row]];
}
.....
Although this code can pass the value to the UIViewController(ParentViewController),and the UIContainer View was hidden,but when I click the show button again , it was not any effect(I feel the container view was overlap lead to touch lose efficacy).
( by the way, I had try
[self.parentViewController dismissViewControllerAnimated:YES completion:nil];
it's not effect )
Question:
How to hide the container view use the delegate and that can touch the show button show container again?
And What great method to control the UIContainer view show and disappear in ParentViewController and UIContainerView ?
I really thank everyone and you can help me and better than better.
containerView and show button are in different viewControllers. So you can't just hide it. The simple way to achieve it is when you select the cell in containerView, present the ParentViewController, and the view in ContainerViewController will dismiss automatically.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate ContainerViewBLETable:self andSelectedDone:[NSString stringWithFormat:#"%ld",indexPath.row]];
ParentViewController *vc = [[self storyboard] instantiateViewControllerWithIdentifier:#"ParentViewController"];
[self presentViewController:vc animated:YES completion:nil];
}
To show the container, you can just dismiss the ParentViewController that presenting.
1.
- (IBAction)btnAction:(id)sender
{
[self.presentingViewController dismissModalViewControllerAnimated:YES];
}
Or
2. Set up segue to dismiss viewController and use prepareForSegue for delegate to communicate with other viewController.
Also REMOVE vc.view.hidden = YES in delegate you had implemented
-(void) ContainerViewBLETable:(ContainerViewBLETable *)vc andSelectedDone:(NSString *)selectedStr.
I'm trying to follow the View Controller Programming Guide for iOS to implement a container view in my application. At the moment I'm just trying to get an initial first view to load but the label included in the first controller is not being shown. In the end, I hope to be able to control which view is shown in the container by using a segmented control.
Any help would be greatly appreciated.
My Storyboard
ViewController.h
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIView *contentController;
- (IBAction)SegmentedControlValueChange:(UISegmentedControl *)sender;
#end
ViewController.m
#import "ViewController.h"
#import "FirstController.h"
#import "SecondController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
FirstController *firstController = [[FirstController alloc] init];
[self displayContentController:firstController];
}
- (IBAction)SegmentedControlValueChange:(UISegmentedControl *)sender
{
}
- (void)displayContentController: (UIViewController *)content
{
[self addChildViewController:content];
content.view.frame = [self frameForContentController];
[self.view addSubview:content.view];
[content didMoveToParentViewController:self];
}
- (CGRect)frameForContentController
{
return self.contentController.bounds;
}
#end
If FirstController is part of the storyboard, then you'll have to load it from the storyboard.
Try doing
FirstController *firstController = [self.storyboard instantiateViewControllerWithIdentifier:#"yourIdentifier"];
I try to use an UIViewController as an custom ContainerViewController to show certain ViewControllers with custom behavior. I have an UIView "detailsView" property in my ContainerViewController to show the content of the loaded ViewControllers. The problem is that the loaded controller is shown but without any content like buttons. What do I do wrong?
part of my ContainerViewContoller.h:
#property (weak, nonatomic) IBOutlet UIView *detailsView;
#property (strong, nonatomic) UIViewController *currentViewController;
the viewDidLoad method of my ContainerViewContoller.m:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"called");
SWResultViewController *swResultViewController = [[SWResultViewController alloc]init];
self.currentViewController = swResultViewController;
// this line doesn't help to show the buttons
swResultViewController.view.frame = self.detailsView.bounds;
[self addChildViewController: self.currentViewController];
[self.detailsView addSubview: self.currentViewController.view];
[self.currentViewController didMoveToParentViewController:self];
}
should be shown:____________________________________is shown:
___________
I have the delegate working as the data is being passed from the modal to the presenting view controller. But the presenting view controller isn't showing the data it receives from the modal. I looked at other posts and they say to use the delegate/protocol method, but don't explain how/why the presenting VC refreshes. I'm assuming my delegate is setup incorrectly. Otherwise, what is the method to refresh the data? I've checked and the viewWillAppear and viewDidAppear doesn't get called.
SCCustomerDetailVC.h (Presenting VC)
#import "SCCustomersVC.h"
#interface SCCustomerDetailVC : UIViewController <SCCustomersVCDelegate>
#property (atomic, strong) SCCustomer *customer;
#property (strong, nonatomic) IBOutlet UIButton *changeCustomerButton;
- (IBAction)changeCustomerButtonPress:(UIButton *)sender;
#end
SCCustomerDetailVC.m (Presenting VC)
- (IBAction)changeCustomerButtonPress:(UIButton *)sender
{
UINavigationController *customersNC = [self.storyboard instantiateViewControllerWithIdentifier:#"customersNC"];
SCCustomersVC *customersVC = (SCCustomersVC *)customersNC.topViewController;
customersVC.delegate = self;
[self presentViewController:customersNC animated:YES completion:nil];
}
//Protocol methods
- (void)passCustomer:(SCCustomer *)customer
{
self.customer = customer;
//At this point, self.customer has the correct reference
[self dismissViewControllerAnimated:YES completion:nil];
}
SCCustomersVC.h (Modal VC)
#import "SCCustomersVCDelegate.h"
#class SCCustomerDetailVC;
#interface SCCustomersVC : UIViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate>
#property (weak, nonatomic) id <SCCustomersVCDelegate> delegate;
#end
SCCustomersVC.m (Modal VC)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SCCustomer *customer = [self customerAtIndexPath:indexPath];
[self.delegate passCustomer:customer];
}
SCCustomersVCDelegate.h
#class SCCustomer;
#protocol SCCustomersVCDelegate <NSObject>
#optional
- (void)passCustomer:(SCCustomer *)customer;
#end
I think you're nearly there. EDIT - just learned here that viewWillAppear behavior is different in iOS>5. You still want view will appear to update your view with your model state, since it needs to do that on initial presentation.
And it's fine to call it from either your modal vc or from within the delegate method. So add code to viewWillAppear that updates the view with the view controller's model state...
// SCCustomerDetailVC.m
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// making up an IBOutlet called someLabel
// making up a model method (description) that returns a string representing your model
self.someLabel.text = [self.customer description];
}
Then either from the presented vc or the delegate, call viewViewWillAppear:
- (void)passCustomer:(SCCustomer *)customer
{
self.customer = customer;
[self viewWillAppear:YES];
[self dismissViewControllerAnimated:YES completion:^{}];
}
You should reload your UI after setting the "customer"
- (void)passCustomer:(SCCustomer *)customer
{
self.customer = customer;
//At this point, self.customer has the correct reference
[self dismissViewControllerAnimated:YES completion:^{
// reload your UI here or call a method which will reload your ui
// e.g. for tableView it will be [tableView reload];
}];
}
I am trying to create a view which contains three subview having different view controller (UICollectionViewController,pageviewcontroller and uiviewcontroller).
i am able to add a uiviewcontroller but other two controller is not allowed.
I am getting this error.....
Incompatible pointer types sending 'UICollectionView *__weak' to parameter of type 'UIViewController *'
Is their any way to add these controller to my subview?
I don't know why you want to add ViewControllers inside a view, i never need it.
I tried to do that, if can help you this is my running code:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (nonatomic, retain) UICollectionViewController *collectionViewController;
#property (nonatomic, retain) UIPageViewController *pageViewController;
#property (nonatomic, retain) UIViewController *simpleViewController;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize collectionViewController;
#synthesize pageViewController;
#synthesize simpleViewController;
- (void)viewDidLoad
{
[super viewDidLoad];
UICollectionViewLayout *layout = [[UICollectionViewLayout alloc] init];
collectionViewController = [[UICollectionViewController alloc] initWithCollectionViewLayout:layout];
pageViewController = [[UIPageViewController alloc] init];
simpleViewController = [[UIViewController alloc] init];
// Do your stuff with this controllers
[self.view addSubview:collectionViewController.view];
[self.view addSubview:pageViewController.view];
[self.view addSubview:simpleViewController.view];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
You don't add view controllers to views. You add views to views (as subviews) and, much more rarely, controllers to controllers (as child controllers).
Think of them as two parallel hierarchies: Given ControllerA that controls view ViewA, you want to make ControllerB a child controller of ControllerA such that it's view, ViewB is a subview of ViewA.
See the WWDC 2011 video: "Implementing UIViewController Containment"