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.
Related
I have Collection View Controller PatientList -> on selection of cell navigates to PatientdetailView -> on click of button navigates to startDignosisView. This is Navigation controller stack. Now from Patient List I have button "ADD" that navigates to AddpatientView, from where I have to navigate to StartdignosisView without disturbing Navigation stack. How can I do it?
for (UIViewController *controller in self.navigationController.viewControllers)
{
if ([controller isKindOfClass:[NeededViewController class]])
{
[self.navigationController popToViewController:controller
animated:YES];
break;
}
}
if let viewControllers = self.navigationController?.viewControllers {
var newStack: [UIViewController] = []
for viewController in viewControllers {
newStack.append(viewController)
if viewController is StartdignosisView {
break
}
}
self.navigationController?.viewControllers = newStack
}
try like this:
some *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"some identifier you add to a vc in the storyboard"];
[self.navigationController pushViewController:vc animated:YES];
Just set the identifier to the storyboard for that view controller.
If you are not using storyboard then follow the below steps:
See if you Add Patient and then directly navigate to StartDignosisVC then you will not be able to pop to PatientDetailVC
You can do any one from these two:
First:
Try to present your AddPatientVC, add new and then dismiss it and follow your old stack path.
Second:
One ADD button action instantiate your AddpatientView like this:
AddPatientVC *obj = [storyboard instantiateViewControllerWithIdentifier:#"AddPatientVC"];
And similarly navigate to StartdignosisView with setting a flag that you are coming from AddPatientVC:
StartDignosisVC *obj = [storyboard instantiateViewControllerWithIdentifier:#"StartDignosisVC"];
obj.isFromAddPatientView = true
When you press Back button from StartDignosisVC then check if you came from AddPatientVC to directly pop it to Patient list.
If you are using storyboard then you can do the following see attached screen shot:
Thanks Mayank for your answer: following code worked in my case.
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
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.
I have an UITabBarController that has 3 buttons. The second button points to ViewController1 which is connected to another view called ViewController2. After I tap a button in ViewController2 I programmatically present ViewController1 again, that works perfect except one thing. After I "arrived" to ViewController1 the tab bar disappears.
I'm using this method to navigate back to ViewController1. (exactly I navigate to its navigation controller, but already tried with the view)
- (void)presentViewControllerAnimated:(BOOL)animated {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"storyboard" bundle:nil];
UINavigationController *firstViewNavigationController = [storyboard instantiateViewControllerWithIdentifier:#"destination"];
[self presentViewController:firstViewNavigationController animated:animated completion:nil];
}
I call here the first method
- (void)didTapButton:(id)sender {
UIButton *button = (UIButton *)sender;
CGPoint pointInSuperview = [button.superview convertPoint:button.center toView:self.tableView];
[self presentViewControllerAnimated:YES];
}
This method hides the tab bar in the ViewController2, I already tried without it, therefore there is no problem with it.
-(BOOL)hidesBottomBarWhenPushed
{
return YES;
}
I can't figure out why this thing happens, I think it's a fair solution, that worked well for a several times when I needed to present views. I've read it can happen with segues, but I'm doing it with code without segues.
Actually your code works right. There should not be tab bar when you present FirstViewController from SecondViewController. Because when you call instantiateViewControllerWithIdentifier its basically creates a new instance of that view controller, and of course, there is no tab bar.
The right way to go back to your first view controller is to pop SecondViewController (or dismiss it, if it presented modally). So your final code should be like this
- (void)didTapButton:(id)sender {
// If this view controller (i.e. SecondViewController) was pushed, like in your case, then
[self.navigationController popViewControllerAnimated:YES];
// If this view controller was presented modally, then
// [self dismissViewControllerAnimated:YES completion:nil];
}
And of course, your view controller hierarchy in storyboard must be like this:
-- UINavigationController -> FirstViewController -> SecondViewController
|
->UITabBarController____|
-...
-...
I've tried the same and got the same result.
My solution was simple, on the push do this :
UINavigationController *firstViewNavigationController = [storyboard instantiateViewControllerWithIdentifier:#"destination"];
firstViewNavigationController.hidesBottomBarWhenPushed = true; // Insert this and set it to what you want to do
[self presentViewController:firstViewNavigationController animated:animated completion:nil];
and then remove your
-(BOOL)hidesBottomBarWhenPushed
{
return YES;
}
In my program I have six view controllers. To navigate among these view controllers I used UINavigationController.
I will explain this issue using two view controllers.
In first view controller, I implemented a button action like this
- (IBAction)clickSearch:(id)sender{
[self gotoSearch];
}
-(void)gotoSearch
{
NSArray *vc = [self.navigationController viewControllers];
ViewControllerSearch *vcSearch = nil;
for (int i = 0; i < [vc count]; i++)
{
UIViewController *tempVC = [vc objectAtIndex:i];
if ([tempVC isKindOfClass:[ViewControllerSearch class]])
{
vcSearch = [vc objectAtIndex:i];
break;
}
}
if (vcSearch)
{
//If exists inside stack the pop
[self.navigationController popToViewController:vcSearch animated:YES];
}
else
{
//If not exists inside stack push ViewController3
ViewControllerSearch *vc3New = [self.storyboard instantiateViewControllerWithIdentifier:#"vcsearch"];
[self.navigationController pushViewController:vc3New animated:YES];
vc3New = nil;
}
}
second view controller has a button and that button action is also implemented as above.
if I move to second view controller from first view controller ,memory increasing.(its ok)
if I move to first view controller from second view controller, memory level not changing.
again I move to second view controller from first view controller ,memory increasing.you can see it in this image.
(memory is not reducing)How can I reduced memory?
first time first to second : NSArray *vc has one object (first VC)
second to first : NSArray *vc has two object (first VC,and second VC)
now im in first view controller.now im click to move second view controller : NSArray *vc has only one object (first VC).second vc missing.and increasing memory (i think it for new second vc)
I asked a question similiar to this before and got many answers first of all thanks for them but because of the complexity of the project I didnt understand the answer so I decided to ask it again this time in a very simple form.
I have one button in viewcontrollerA and I want that button to write on a Label which is in viewcontrollerB.Its simple a button at A will set the Label text on B.
Example
User opens the app
Clicks the button at page A
Second Page comes up and in that page label text is set by the label.text code came from viewcontroller A it calls the code
Or maybe I can call the code of A from B its not important as long as I make it.I can make butons to open another viewcontrolers so you dont need to explain it.
Also if any other ways around and as long as they are simple I can do them too.Maybe I wrote the code elsewhere and call it from A and B.
Please explain it step by stem cause I have little knowlage about objective C and xcode.
I ask this question to learn about connections between viewcontrollers.In reality I will make that button to display a random number at the second page but its not important rightnow cause if I learn to make simple connection I can do the rest.
In your action, you need to have a reference to the second view controller. For example
- (IBAction)buttonAClicked:(id)sender {
ViewController2 *vc2 = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:nil];
[self.navigationController pushViewController:vc2 animated:YES];
vc2.someVariable = #"This is random text";
[vc2.someButton setTitle:#"Some button text" forControlState:UIControlStateNormal];
}
This shows how you would create a second view controller, change two properties, and then push it.
In your second view controller create a property called theText that is an NSString and then in the viewDidLoad assign the label.text to the NSString;
- (void)viewDidLoad
{
if(self.theText)
self.label.text = self.theText;
}
Now use your first view controller to set theText in the second view controller.
If you are using a segue use prepareForSegue:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"Second View Segue"])
{
SecondViewController *theController = segue.destinationViewController;
theController.theText = #"Some text";
}
}
If you are using some sort of modal presentation:
SecondViewController *theController = [[SecondViewController alloc] init];
theController.theText = #"Some text";
[self presentModalViewController:theController animated:YES];
or if you are using a navigation controller:
SecondViewController *theController = [[SecondViewController alloc] init];
theController.theText = #"Some text";
[self.navigationController pushViewController:theController animated:YES];
So your first view controller will set the NSString property in the second, then the second will set the UILabel equal to the NSString during it's load. You can not set the text of a UILabel before the second view controller is loaded, so something like:
SecondViewController *theController = [[SecondViewController alloc] init];
theController.label.text = #"Some text";
[self.navigationController pushViewController:theController animated:YES];
will not work correctly, because you can't set the text for the label until the view is loaded.
Hope that helps.