I have two views in the Tab Bar View. I want my second view to inform first view, when its Text Fields have changed value. I've done all the necessary coding for it, but there is one problem - first view doesn't see connected label outlets in the method declaration.
Code of the second view:
- (IBAction)textFieldHasChanged:(UITextField *)sender {
id<HPAAddCarOverallInfoTVCDelegate> strongDelegate = [[HPAAddCarMainViewController alloc] init];
if([strongDelegate respondsToSelector:#selector(addCarOverallInfoVC:textFieldValueChanged:)]) {
[strongDelegate addCarOverallInfoVC:self textFieldValueChanged:sender.text];
}
}
Code of the first view:
-(void)addCarOverallInfoVC:(HPAAddCarOverallInfoTableViewController *)viewController textFieldValueChanged:(NSString *)value
{
self.overallVCFieldCount.text = value;
NSLog(#"%#", value);
}
self.overallVCFieldCount.text = value; - value exist, but textField doesn't.
As I think, problem belongs at this line of code:
id<HPAAddCarOverallInfoTVCDelegate> strongDelegate = [[HPAAddCarMainViewController alloc] init];
I guess, that delegate isn't exact view with which I am working with. Bouth views are loaded at the same time via storyboard. If I am correct with my thought, can you tell me please, how can I give a pointer to exact first view which as second view are loaded when Tab Bar View controller goes on the screen?
You're creating a new view controller in textFieldHasChanged. If you have that view controller in IB, instantiate it like this:
UIStoryboard *st = [UIStoryboard storyboardWithName:[[NSBundle mainBundle].infoDictionary objectForKey:#"UIMainStoryboardFile"] bundle:[NSBundle mainBundle]];
id<HPAAddCarOverallInfoTVCDelegate> strongDelegate = st instantiateViewControllerWithIdentifier:#"identifier"];
Where identifier is the identifier you have given your view controller in your storyboard.
Related
I am using this to implement ContainerViewContoller. Everything is going fine but I'm unable to pass data from one child ViewController to an other child ViewContoller.
CouponCodeViewController *couponVC = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"CouponCodeViewController"];
couponVC.coponcode=#"this is data";
couponVC.title = #"Enter Coupon Code";
[couponVC viewWillAppear:true];
CategoryViewController *categoryVC = [self.storyboard instantiateViewControllerWithIdentifier:#"CategoryViewController"];
categoryVC.title = #"Choose A Category";
YSLContainerViewController *containerVC =
[[YSLContainerViewController alloc]
initWithControllers:#[couponVC,categoryVC]
topBarHeight:statusHeight + navigationHeight
parentViewController:self];
When I call my container ViewController it loads all childVC at the same time. Now I want to pass data on click from CouponCodeViewController to CategoryViewController but I'm not able to do so because viewDidLoad, viewWillappear, and viewDidAppear are not called
CouponCodeViewController I am going using this:
- (IBAction)skipAct:(id)sender {
// CategoryViewController *category=[[CategoryViewController alloc]init];
// category.userInput=#"this is the data";
[self.scrollMenuDelegate scrollMenuViewSelectedIndex:1];
}
#pragma mark -- YSLContainerViewControllerDelegate
- (void)containerViewItemIndex:(NSInteger)index currentController:(UIViewController *)controller
{
[controller viewWillAppear:YES];
}
In CategoryViewController my viewDidLoad and viewDidAppear are not called.
How can I pass data from childVC to another ChildVC.
That because when you init all controllers, the parent controller doesn't do 'addChildViewController'. It does that only when showing a new controller (I've looked the code).
And after it move from this controller, it removes it from the controller hierarchy.
I would use either delegate or notification to pass the data.
Another option (which I don't like) is to give the coupons controller a reference from the categoryViewController.
I have a UINavigationController which points to a UITableViewController (a list of items) where there is a segue from a cell to another UITableViewController (a screen to edit an item).
On first run of the application, I'd like to skip the first list and immediately go to the second screen, to edit a new item.
The problem is I need to pass the first UITableViewController, as I need to be able to go back to that one (or is there a way to set the controller the back button is pointing to?).
Things I've tried and failed:
Set a boolean shouldPresentNewItem on the UINavigationController and in the viewDidLoad if it is set to true, present the first UITableViewController, also setting a boolean so I can go to the edit screen.
Using self.navigationController!.popToViewController(arr[index] as UIViewController, animated: true) in the UINavigationControllers viewDidLoad. This gave an error as self.navigationController was nil. (I don't get why this happens)
How can this be done?
In navigation controller set some boolean indicating that you're going to show edit screen and in viewDidLoad just push edit view controller without animation:
- (void) viewDidLoad {
[super viewDidLoad];
if (self.presentEditScreen) {
self.presentEditScreen = NO;
EditViewController *e = [[DetailViewController alloc] init];
[self pushViewController:e animated:NO];
}
}
simplest way will be. just push from second view to first view
firstViewController *objFirstViewController = [[firstViewController alloc]initWithNibName:#"firstViewController" bundle:nil];
[self.navigationController pushViewController:objFirstViewController animated:No];
I have two view controllers. First is empty, second contains a text field. If this field is empty, I need to move to the second controller automatically.
I tried this:
NSUInteger VCcount = self.navigationController.viewControllers.count;
UIViewController *btVC = self.navigationController.viewControllers[VCcount-2];
if([self.btViewController.Text.text isEqualToString:#""])
{
[self.navigationController pushViewController:btVC animated:YES];
}
and this:
UIViewController* btVC = [storyboard instantiateViewControllerWithIdentifier:#"BTViewController"];
But at the first launch program knows only current controller and doesn't know about thesecond.
How can I get there?
See the example below:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.textField.text = #"some text";
if (self.textField.text.length == 0) {
UIViewController *secondVC = [self.storyboard instantiateViewControllerWithIdentifier:#"secondVC"];
[self.navigationController pushViewController:secondVC animated:NO];
}
}
If you comment out the assignment of "some text" to the textField, the secondVC will be instantiated and presented. I don't know what exactly you are trying to achieve with first two lines of your presented code.
If the secondVC already exist, you can just take a reference to it by knowing its index on the stack, or inspecting viewControllers array of your navigationController before you push it to the stack. If it does not exist, you just instantiate it from storyboard (with the correct identifier) and push it.
I have 3 different buttons which upon touch present the same UINavigationViewController with a container.
However, each button represents which view controller will be embed at the container.
How can I embed the necessary viewController by code?
what you can do is use an identifier which would be assigned to your various viewController as storyboardID
such as fisrtVC, SecondVC, thirdVC
the depending upon whichButton is pressed just set the identifier and use this identifier when
you want to push the controller such as
for example
while you push the navigation viewController just pass the storyboard Identifier such as
Declare a NSString *identifier;
-(IBAction)firstButtonClicked{
identifier=#"firstVC";
//pass this identifier to your navigationController
}
similarly for other Controllers
When you push the navigation controller make sure to pass this identifier along now depending upon the value you can initiate the controller on you VC as
on ViewDIdApppear:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
NSString* viewType = passedIdentifier
UIViewCOntroller* viewController = [storyboard instantiateViewControllerWithIdentifier:viewType];
Load this "viewCOntroller in your ContainerView"
You should implement prepareForSegue method:
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
id is your button that will fire segue. You do segues by drugging and drop in storyboard. Put an if statement in this method and tell your UIViewController which UIView to load in container. You can pass data like this:
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
[vc setMyObjectHere:object];
Second snippet taken from this answer.
Update.
To load different UIView in container put if statement into viewWillApper method.
This method firing earlier than viewDidLoad. If statement must check some property that tell what UIView to init. You setting up this property in prepareForSegue.
It will look like this:
if (self.viewToLoad == 1)
{
self.dynamicView = MyCustonUIViewNumberOne *view = [MyCustonUIViewNumberOne alloc] init];
}
Update 2.
Or you can do it dynamically like in this answer:
if (self.viewToLoad == 1)
{
// Replacing with your dimensions
CGRect frame = CGRectMake(x, y, width, height);
MyCustonUIViewNumberOne *dynamicView = [[MyCustonUIViewNumberOne alloc] initWithFrame:frame];
[self.container addSubview: dynamicView];
} else {
// Init other view
}
The container property:
I am trying to have a different view controller appear as you change the device orientation and for that I am using a UINavigation Controller. When I call for the other view controller to be pushed [self.navigationController pushViewController:graphView animated:YES]; It makes the transition but the screen is black and does not load this new controller "graphView"'s view which is white with text. I have done graphView = [[GraphView alloc] init]; for the new controller but i do not have any storyboard connections made from the current view to the graph view nor do I have anything in my new view controller other than:
- (void)viewDidLoad {
//[super viewDidLoad];
NSLog(#"loaded");
}
Is there an extra step since this is a new view controller to load the view from this view controller that i have on my storyboard? Also the log does work meaning that is corrent.
Instead of initializing your 'graphView' like:
graphView = [[GraphView alloc] init];
You'll need to do this:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
graphView = [storyboard instantiateViewControllerWithIdentifier:#"YourViewControllerId"];
**And make sure you set your ViewController's storyboard identifier in the storyboard:
Select your ViewController
Click the Identity inspector
Set the Storyboard ID ('YourViewControllerId' above)
Then, calling pushViewController:animated: as you were should present your ViewController appropriately.