How to change container in another VC ? iOS - ios

In ViewController i have two property of containers:
#property (weak, nonatomic) IBOutlet UIView *firstContainerView;
#property (weak, nonatomic) IBOutlet UIView *secondContainerView;
And i can do everything with them:
self.firstContainerView.alpha = 0;
self.secondContainerView.alpha = 1;
But how i can appear firstContainerView from SecondVC method (click button) ?

First of all you must have a pointer to access the target view controller so you see two vc not have a connection so you should create a global pointer for another vc to access. You can create a singleton to hold these vc or just use a delegate or block.

Why don't use a delegate to inform ViewController that button is clicked and ViewController will take care of appearing/disappearing the containers views.

Related

iOS Container View and Parent ViewController communication?

How can I communicate with container view controller and parent view controller? I've tried to make a communication and pass the value between them. I've added a container view in the green view controller. And I had set segue name with "communicateSegue". I've searched some methods, I know we can set the prepareForSegue to pass the value at initial.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"communicateSegue"]) {
NSLog(#"call prepare for segue at parent view controller");
}
}
But now I want to pass value and change the label in the different viewcontroller . Not at the initial.
I don't know how to do?
Question:
Have anyone know how to implement ParentViewController pass value to Container View Controller and show the label in the ContainerViewController?
And reverse , Container View Controller click the button then pass the value and change the label show in the ParentViewController with objective-c?
Thanks.
My declare variable in parentViewController.h:
#import
#interface ParentViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *parentTF;
#property (weak, nonatomic) IBOutlet UIButton *passValToChildVCBtn;
#property (weak, nonatomic) IBOutlet UILabel *showContainerValLB;
#property (weak, nonatomic) IBOutlet IBAction *passValueToContainerEvent;
#end
In the ContainerChildViewController.h
#import
#interface ContainerChildViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *showParentValLB;
#property (weak, nonatomic) IBOutlet UITextField *childTF;
#property (weak, nonatomic) IBOutlet UIButton *passToParentBtn;
#property (weak, nonatomic) IBOutlet IBAction *passValueToParentBtnEvent;
#end
test project in the here.
thank you very much.
Regarding passing value to the containerView controller, you can make a property in the ChildViewController of the value you want it to be passed. Then in your ParentViewController do something like the following:
self.ChildViewController.yourProperty = yourValue
The opposite can be done in 4 ways:
You can make a delegate protocol to communicate the data between your controllers.
You can post a notification in your ChildViewController and add the parent controller as an observer.
You can use KVO.
And the easiest way out, you can make a property in your parentviewController and access it like the following
((YourParentViewControllerClassType *)self.parentViewController).yourParentProperty = TheValueYouWant;
I do it like this:
set identifier for segue from your containerView to viewController
make property/variable myChildViewController in your parent view controller and property/variable myParentViewController in your child view controller
in your prepareForSegue method set this properties to be the reference to right objects
Now you can access to properties of parent/child view controller through this references.
Example in Swift:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "YourIdentifier" {
// Set references
myChildViewController = segue.destinationViewController as! YourChildViewController
myChildViewController.myParentViewController = self
}
}
Example in Objective C
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"YourIdentifier"]) {
// Set references
myChildViewController = [segue destinationViewController];
myChildViewController.myParentViewController = self
}
}
I did't try the objective C code becouse I don't ever use it. It is just an example to get the idea.
After that you can set any property of parent from child view controller as:
myParentViewController.property = value
and in your parent view controller:
myChildViewController.property = value
Hope this helps anyone!
Is pretty simple, the UIStoryboardSegue contains a reference to your destination view controller using the property -destinationViewController.
In the method -prepareForSegue you can access it and pass the data that you need.
If you need to pass data from child to parent, I strongly suggest you to avoid hard coupling and use something such as delegation or notification pattern.
Remember that your parent view controller already contains a reference to you child view controllers and you can simply access it by using -childViewControllers property.
you can use NSNotificationCenter for updating all screens or you can do this way..
create a property in ContainerChildViewController.h
#property(nonatomic,copy)NSString * mytextString;
this property will be accessible in your ParentViewController.h if you import ContainerChildViewController.h
you have to create a NSString in ParentViewController.h
in this you can set button action to copy textfielddata.text
then you can assign this value to your ContainerChildViewcontroller's
as
// create an instance of 2nd view controller as second in ParenViewController
UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ContainerChildViewController * second= [mystoryboard instantiateViewControllerWithIdentifier:#"ContainerChildViewController"];
second.mytextString = self.mytextString;
// either you directly pass this value or use the string it should work both ways
NSLog(#"%#",second.orderID);
[self.navigationController pushViewController:second animated:YES];
Reply if it works
try this
- (IBAction)showDetail:(UIButton *)sender {
DetailViewController *detailVc = [self.childViewControllers firstObject];
detailVc.lable.text = sender.titleLabel.text;
}

Update UILabel, UIbutton to second view controller imported from first view controller

I am using tab bar navigation/I am a newbie.
I have ViewController1 which has all the IBOutlet UILabel, UIButton AND also some IBAction functions. I would like to pass all of these data to ViewController2.
this is what i try:
I noticed that in ViewController2 after I use: #import "Viewcontroller1.h" -- all these functions/outlets are available on the Main.storyboard. I started to connect these outlets to ViewController2 on Main.storyboard and they seem to work on the first load. HOWEVER, when I interact with the Viewcontroller1 and changing the UILabels, these will not get updated on the Viewcontroller2. Any help is greatly appreciated!!
Regards,
Matt
You have to define different IBOutlets and IBActions for each view controller in its respective .h file and implement it in its respective .m file.
Suppose you have two view controllers with a button named "Back" on each at exact same location and with exact same functionality. Then you'll have to define your IBOutlet and IBAction in the following way:
#interface ViewController1
#property(nonatomic, assign) IBOutlet UIButton *backButton;
-(IBAction)on_back:(id)sender;
#end
#implementation ViewController1
-(IBAction)on_back:(id)sender
{
//your code for doing back action...
}
#end
//similarly as above you'll have to write once
//more in #interface and #implementation of ViewController2.
//Once done, you can bind the respective IBOutlets and IBAction
//from Storyboard or XIB/Nib file.

UIPageViewController in XIB Error

I have a subclassed view controller and in Interface Builder I want a subview of the VC's view to be a UIPageViewController's view. I set the UIPageViewController's datasource to File's Owner and the view property to the subview of my VC. Can this functionality be achieved? or I can't use the UIPageVC in that way? Most of the examples are for storyboards and not the old VC pushed by NavigationController way. I get this exception '[UIView invalidatePageViewController]'.
I had the same thing happen to me when I had a UIViewController as my root view - and my UIViewController had an attribute defined as:
#property (strong, nonatomic) IBOutlet UIPageViewController *pageViewController;
My IBoutlet was also connected to a UIPageViewController in my xib.
The solution: Remove the IBoutlet and disconnect the UIPageViewController from my xib
#property (strong, nonatomic) UIPageViewController *pageViewController;
Maybe the crash is related to 'there should only be one view controller per view'
Also, in the 'viewdidload' if you do
_pageViewController.view = _apageView;
where _apageView is in your UIViewController as:
#property (strong, nonatomic) IBOutlet UIView *apageView;
This will also cause the same crash to happen - therefore you would need to do:
[_apageView addSubview:_pageController.view];
Then the crash shouldn't happen.

disable button from another view controller in xcode

I have a button that is initialized dynamically.. I want to disable that button from another UIViewController.
I am using this code:
The button is
#property (strong, nonatomic) IBOutlet UIButton *aboutus;
and then i try to disable it this way:
OtherViewController * view2 = [[OtherViewController alloc] initWithNibName:#"view2" bundle:nil];
view2.aboutus.enabled=NO;
but the button would still be enabled.. any ideas why?
You need a public BOOL property:
#property(nonatomic) buttonEnabled;
on OtherViewController. Set that value to whatever you want (YES or NO) and then in viewDidLoad:
aboutus.enabled = buttonEnabled;

How to create generic view with viewcontroller for iOS5?

I'd like to develop for iOS5 and have a storyboard...
I've just created UIView with UIViewController on the storyboard.
I have added a lot of other UIButtons and labels and creates outlets to VC.
I would like to use this view with it's viewcontroller 3 times on a single parent view.
How is it possible? I dont want to copy "a lot of other UIButtons and labels" ...
Maybe i should create this view out of storyboard in separate XIB? How will i use XIB in storyboard?
UPDATE:
Thanx you, Juzzz - your solution works perfect:
You have to create 2 custom viewControllers (one for each view in your story board.
example:
#interface GraphCollectionViewController : UIViewController
#interface GraphViewController : UIViewController
To connect them you can use something called: UIViewController containment
For your GraphCollectionViewController create 3 outlets for your UIViews. Then create 3 properties of GraphViewController's (or an array, what you want) and initialize them in the view did load.
#property (strong, nonatomic) IBOutlet UIView *topView;
#property (strong, nonatomic) IBOutlet UIView *middleView;
#property (strong, nonatomic) IBOutlet UIView *bottomView;
#property (strong, nonatomic) GraphViewController *topGraphViewController;
#property (strong, nonatomic) GraphViewController *middleGraphViewController;
#property (strong, nonatomic) GraphViewController *bottomGraphViewController;
...
//top graph
self.topGraphViewController = [storyboard instantiateViewControllerWithIdentifier:#"GraphViewController"]; //init with view from storyboard
self.topGraphViewController.view.frame = self.topView.bounds; //set frame the same
[self.view addSubview:self.topGraphViewController.view];
[self addChildViewController:self.topGraphViewController];
[self.topGraphViewController didMoveToParentViewController:self];
//middle graph
self.middleGraphViewController = [storyboard instantiateViewControllerWithIdentifier:#"GraphViewController"]; //init with view from storyboard
self.middleGraphViewController.view.frame = self.middleView.bounds; //set frame the same
[self.view addSubview:self.middleGraphViewController.view];
[self addChildViewController:self.middleGraphViewController];
[self.middleGraphViewController didMoveToParentViewController:self];
//bottom graph
self.bottomGraphViewController = [storyboard instantiateViewControllerWithIdentifier:#"GraphViewController"]; //init with view from storyboard
self.bottomGraphViewController.view.frame = self.bottomView.bounds; //set frame the same
[self.view addSubview:self.bottomGraphViewController.view];
[self addChildViewController:self.bottomGraphViewController];
[self.bottomGraphViewController didMoveToParentViewController:self];
I think you get the point. For more understanding this example .
You can create a new view class (with it's own .h, .m files) and base this on the ViewController you created yourself.
So as for code:
#interface ViewController : UIViewController
Let's say the above is your original ViewController that you want to use in other places.
This has buttons, labels, etc. in it.
When you create a new view class base it on your own instead of UIViewController class like this:
#interface MyNewController : ViewController
Now that MyNewController is based on ViewController you created earlier, it should have it's buttons, labels, etc. you created as well.
Edit: You might also have to change your view's base class in the storyboard.
Click on the view you want to change, look at the right hand side attributes window, under Custom Class choose your own controller, in this case ViewController.

Resources