UITableView delegate not called when UIViewController is popped - objective-c

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.

Related

iOS 8 UISplitViewController delegate not responding

I'm transitioning my app to iOS 8, and I've decided to use a SplitViewController because its new functionality finally allows me to do what I want. I present the SVC modally on iPad, and the SVC is the root view controller of the full-screen cover vertical transition. From the presenting view controller:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
plotSplitViewController = segue.destinationViewController;
plotViewController = (PlotViewController *)[[[segue.destinationViewController viewControllers] objectAtIndex:1] topViewController];
plotViewController.inventory = _inventory;
if ([plotViewController view]) [plotViewController setPlot:selectedPlot];
}
Then I manually make connections in the PlotSplitViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
self.delegate = self;
// set up controllers
layoutNavigationController = [self.viewControllers objectAtIndex:1];
plotViewController = (PlotViewController *)[layoutNavigationController topViewController];
plotViewController.delegate = self;
// configure split view
[self showInfoPane:NO withTable:infoTableViewController];
self.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;
}
So both the master and the detail get view controllers inside UINavigationControllers (to take advantage of the free toolbar resizing, plus the master pushes a table view hierarchy).
Everything seems fine; the views load as they're supposed to, the delegate method from PlotViewController functions correctly, etc. But as you can see, I assign the Split View Controller to be its own delegate...but it won't respond to any of its own methods, so I can't customize its behavior. I checked to make sure it's set correctly:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(#"split view %# did appear, delegate: %#", self, self.delegate);
}
And it returns the same object (itself) for both values. Is this just a no-no? I read that you can assign a SplitViewController as its own delegate, and I think an object can be a delegate for more than one other object, right? It can certainly implement protocols for more than one. So why is my SplitViewController not able to receive delegate methods for itself? I have NSLogs in all of them, and none are ever called.
Turns out it works if you make your custom view controller a subclass of UIViewController, and add a UISplitViewController programmatically, as a child view controller. Make your VC its delegate, and you can make it behave however you want.

How do I call a function when a segue is exited?

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];
}
}

Superview is Nil after Second Launch of View Controller

I've spent hours and I cant figure this out. I have a detail view controller (UITableView) which is launched here:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
EventLocationDetailController *newDetailViewController = [[EventLocationDetailController alloc] initWithNibName:#"EventLocationDetailController" bundle:nil];
self.eventDetailController = newDetailViewController;
[self.navigationController pushViewController:self.eventDetailController animated:YES];
[newDetailViewController release];
}
In the detail view controller there is a button method which calls the below method to display a slide-in-slide-out animation confirming the users choice:
-(void)confirmLastActionWithMessage:(NSString *)message {
ConfirmActionViewController *newConfirmActionViewController = [[ConfirmActionViewController alloc] initWithNibName:#"ConfirmActionViewController" bundle:nil];
self.confirmActionViewController = newConfirmActionViewController;
[newConfirmActionViewController release];
[[self.view superview] addSubview:self.confirmActionViewController.view];
}
Protocol method called by the ConfirmActionViewController indicating that the animation is finished.
-(void)didFinishConfirmDisplay:(UIView *)viewToRemoveFromSuperview {
[viewToRemoveFromSuperview removeFromSuperview];
}
This works perfect the first time I press the button. If I pop the detail controller and push it back on to the stack and press the button again, nothing happens and the detail controller's superview is nil every time I invoke the method after that. Superview is not nil in the viewWillAppear method for the detail view, only when It gets to the confirmLastActionWithMessage method. No other user interaction happens in between. How do I get the superview back? I have a similar code that works without animation.
I've also noticed that the detail view controller hasn't called dealloc when popped off the stack. Not sure where the problem is.
Thanks.
EDIT 1
OK. I replaced the addSubview line with this one:
[self.view insertSubview:self.confirmActionViewController.view atIndex:0];
and the animation view appeared underneath one of the table cells. Could one of the table cells steal the superview?
Well I don't really understand why you should add the subview to the superview. Why not add it just to self.view
I may not be able to explain why there is no superview but try either adding the controller view to self.view or
[[[[UIApplication sharedApplication] delegate] window] addSubview:yourview];
This will render the view on top of everything.

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];
}

-(void)viewWillAppear:(BOOL)animated doesn't called

My application is view based in my app in one view i write view will appear but this method doesn't call. My code is
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"view will Appear");
[tableView reloadData];
}
Can anyone tell why viewWillAppear method not called.
Sorry I forgot To tell You That This method call first time but when i remove a subview from this view viewWillAppear not called. Please Suggest me how to solve this problem.
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(#"view will Appear");
[tableView reloadData];
}
if still it is not calling then try to call through code , as per example [classobj viewWillAppear:NO];
The viewWillAppear and other related methods are called to the viewcontroller that are linked with the rootViewController of the mainWindow.
So if you are using a view based application, the viewWillAppear method of the first view controller will work properly and others wont.
I think that the problem you are seeing is that viewWillAppear: is a method on a UIViewController, and not a method on UIView. viewWillAppear: is called on the view controller to indicate that the controller's view will become visible.
If you have added the code above to a class based on UIView, that code won't get called. You need to move that code to your view controller -or- you might achieve the result that you are looking for by implementing the didMoveToSuperview method in your UIView based class instead.
didMoveToSuperview will be called on your view when your view is added to another view using addSubview:.
Hi Here I did instead
[self.view addSubview:viewcontroller.view];
I Used this:
[self presentModalViewController:viewcontroller animated:YES];
and write this method now my problem is solved.
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"==========view will appear");
}