How do I call a function when a segue is exited? - objective-c

Currently, my app goes from view A to view B through a segue and performs some functions in prepareForSegue. What should I do if I want to call a function that is executed when view B goes to view A (after pressing the back button on the Navigation Controller)?
I imagine that I could map the "back button" to an IBAction, but I'm not sure how I would do that, since the back button is part of the Navigation Controller and isn't directly visible on the Storyboard.
In particular, view B updates some values that view A has displayed. I want to call viewDidLoad so that view A has the updated data before it loads.
In ViewA's view controller:
// update view when it becomes visible
- (void)viewDidAppear:(BOOL)animated {
[self viewDidLoad];
}

Ah, this isn't a segue as such. This is equivalent to popViewController.
If you want to update the view when view A becomes visible then you can do that in the function...
- (void)viewWillAppear:(BOOL)animated
or in the function
- (void)viewDidAppear:(BOOL)animated
These will run each time the view becomes visible.
In here you can run your "updateView" method or whatever method you want.
If you want to pass data back to view A (i.e. view B is a "select city" view or something) then you show make view A a delegate of view B. That way you can pass the info back when the user does something.
Instead of running viewDidLoad do this...
- (void)viewDidLoad
{
[self.button setTitle:#"blah"];
[self updateView];
}
- (void)viewDidAppear:(BOOL)animated
{
[self updateView];
}
- (void)updateView
{
// do something that you want to happen
}
You shouldn't actually have to do this though. It is enough just to run [self updateView] from viewDidAppear.
You can't run viewDidLoad directly though.

In view controller "A" you need to implement the method prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender and inside create a segues destinationViewcontroller, heres a example:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:SEGUE_FOR_OPTIONS])
{
// Get reference to the destination view controller
OptionsViewController *optionVC = [segue destinationViewController];
[optionVC someMethod];
}
}

Related

Navigation Bar subview tree might get corrupted issue

i am trying to send the view to next view but when i try to come back to the root page it crashes and say that Navigation Bar subview tree might get corrupted issue
- (IBAction)nxtBtn:(id)sender {
//here i am sending it to next view...
[self performSegueWithIdentifier:#"next" sender:(id)sender];
}
//function for segue
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//next is the name of the identifier
if ([segue.identifier isEqualToString:#"next"]) {
nextViewController *vc=(nextViewController *)segue.destinationViewController;
vc.str=sender;
}
}
we don't need any kind of identifier for simple use of segue i.e. navigating from one view to another without passing any data. just simple as that you have to connect the segue from one view to other and run the application. it will work properly.

Object becomes Nil when pushing controller

I have a the first application controller, MAViewControllerMenu, and when that controller loads, I already allocate the next controller, imageControllerView.
- (void)viewDidAppear{
[super viewDidAppear:(YES)];
if (!imageControllerView)
imageControllerView = [[self storyboard] instantiateViewControllerWithIdentifier:#"chosenImageController"];
}
Then, I select an image from the image picker, and want to move to the next controller,imageControllerView, where the image would be displayed. I set the next window's image property as follows:
imageControllerView.image = [[self.pageViews objectAtIndex:(centered_image_ind)] image];
This line works, I checked that there's a value in imageControllerView.image.
However, when I move to the next controller,imageControllerView , I notice that the memory address of imageControllerView changes, or in other words, imageControllerView's properties that I change before moving to that controller, specifically image, reset when I move there.
Instead of throwing code here, I was hoping you could let me know what I should provide.
I think it's a common problem people know of:
Controller's objects re-init'ing when moving from one controller to another.
Here's a screen shot that might give a hint of what Im trying to do
Left most one is where I select pictures which in turn go into the slide show scrollview. Then I click next, and the image is supposed to appear in the centered ImageView
Thanks
OK...
You cannot "already allocate the next view controller" this won't work. There is no point in creating it like this at all. You can delete the imageViewController property (or iVar) completely.
The arrows that you have between the view controllers in your storyboard are segues. In Interface Builder you can select a segue and give it an identifier. For instance you would use something like #"ImageViewSegue".
I guess the segue is attached to the Next button. This is fine.
Now, in your MAViewControllerMenu you need to put this method...
- (void)prepareForSegue:(UIStoryBoardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ImageViewSegue"]) {
// the controller is CREATED by the segue.
// the one you create in view did load is never used
ImageViewController *controller = segue.destinationController;
controller.image = [[self.pageViews objectAtIndex:(centered_image_ind)] image];
}
}
Now for the segues in the other direction...
You appear to be using segues to dismiss the modal views. You can't do this. What it will do is create a new view controller and present that instead of dismissing the presented view.
i.e. you'll go...
A -> B -> C -> B -> A -> B
// you'll now have 6 view controllers in memory
// each segue will create a fresh view controller with no values set.
What you want is...
A -> B -> C
A -> B
A
// now you only have one view controller because the others were dismissed.
// when you dismiss a view controller it will go back to the original one.
// the original one will have all the values you set previously.
To do this you need to create a method something like...
- (IBAction)dismissView
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Then whatever the button is for your dismiss action attach it to this method.
Now delete all the backwards curly segues.
Passing info back
To pass info back to the original view controller you need a delegation pattern or something similar.
You can read more about creating a delegate at This random Google Search
Create a delegate method something like...
- (void)imageViewSelectedImage:(UIImage *)image;
or something like this.
Now when you do prepareForSegue you can do...
controller.delegate = self;
and have a method...
- (void)imageViewSelectedImage:(UIImage *)image
{
// save the method that has been sent back into an array or something
}
I might be wrong, but seems you go to your second view controller using a segue, it is normal your controller instance isn't the same than the one retrieved by [[self storyboard] instantiateViewControllerWithIdentifier:#"chosenImageController"]
you should take a look at - (void) prepareForSegue:(UIStoryboardSegue *)segue
(UIViewController method)
inside this method set your image property to the segue destination controller (check the identifier of the segue)

Show different view on navigation controller when data is empty using storyboard

I have a navigation controller with a tableview controller as the first controller, however when the database is empty I want to show the user a view that asks the user for some information to fill the database and show it in the navigation controller instead of the view assigned in storyboard, I guess I would have to do this programmatically, but I'm new to iphone development and honestly dont know where to start.
Here's how you can do it. Create a new scene in your storyboard for your view controller where the user will submit the info (let's say it's called CollectInfoViewController). Then create a modal segue from your tableview controller to the CollectInfoViewController. In the Attributes Inspector, set the Identifier property of the segue to "CollectInfo" so you can identify it later.
Then when your tableview controller's viewDidLoad method runs, ask the table view delegate whether there are any rows to show. If there are not, programmatically perform the segue to your CollectInfoViewController.
- (void)viewDidLoad
{
[super viewDidLoad];
if ([self.tableView.dataSource tableView:self.tableView numberOfRowsInSection:0] == 0) {
[self performSegueWithIdentifier:#"CollectInfo" sender:self];
}
}
In your CollectInfoViewController, once the user has entered the information and you have stored it in your database then you can call the following from within CollectInfoViewController to dismiss that view. This will return the user to the tableview.
[self dismissModalViewControllerAnimated:YES];
Finally, back in your tableview controller, you might need to reload your table with the new data that's been collected. You can do that in viewWillAppear, which will be called when the modal view controller is dismissed.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView reloadData];
}

UITableView delegate not called when UIViewController is popped

I have a view controller that contains a UITableView. When the view controller gets pushed onto the stack, the table view delegate methods get called and it populates the table.
Then I push another view controller onto the one that contains the table view. What I would like to make happen is that - when the second view controller gets popped and I return to the previous view controller, those uitableview delegate methods get called again (so as to repopulate the table).
In other words, how do you repopulate a uitableview when popping to a view controller.
Thanks
In viewDidLoad or viewDidUnload, viewWillAppear, viewWillDisappear (whichever of these is right for your situation) you can put [myTable reloadData];:
// If you can include some code it would help as I am a bit uncertain
// about exactly what you are trying to do from the question but
// you should use whichever of these is correct for project:
- (void)viewDidLoad {
[super viewDidLoad];
[myTable reloadData];
}
- (void)viewDidUnload {
[myTable reloadData];
}
- (void)viewWillAppear {
[super viewWillAppear];
[myTable reloadData];
}
- (void)viewWillDisappear {
[super viewWillDisappear];
[myTable reloadData];
}
What you should do is add a [self.tableView reloadData] (or whatever your table variable is) call inside the viewWillAppear method of its view controller. This will cause the table view to be reloaded both when being pushed (as it does now) and when other view controllers are popped to reveal it.

Using a UITable in a UIViewController

I've got a UIViewController with a xib view that has a button and a table.
Everything is wired up, the data has rows in it etc. But if i click a row and navigate away from this initial screen, then go back, the cell in the table still has the highlighted state on it.
Do i need to implement methods other than numberOfSectionsInTableView, tableView:cellForRowAtIndexPath and tableView:didSelectRowAtIndexPath?
Implement -viewWillAppear: on your view controller and deselect the table's currently-selected row, something like this:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated];
}