Using a UITable in a UIViewController - objective-c

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

Related

Calling reloadData on same UITableView, but it seems like it's calling on a different one

This has been a headache for few hours now and I finally found out what is actually happening, but I don't know how to solve this issue.
I've got List.h with UITableView properly connected from storyboard:
#property (strong, nonatomic) IBOutlet UITableView *tableView;
Then there's List.m where I set delegates and datasource for my UITableView:
// Set tableview datasource and register class for cell reuse
self.tableView.dataSource = self;
[self.tableView registerClass:[TableViewCell class] forCellReuseIdentifier:#"cell"];
// Set tableview delegate
self.tableView.delegate = self;
// Set tableview cells style
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.backgroundColor = [UIColor colorWithWhite:0.1f alpha:1.0f];
// Set tableview frame
self.tableView.frame = CGRectMake(0.0, 35.0, self.tableView.frame.size.width, self.tableView.frame.size.height-35.0);
Then on NSNotification I'm trying to [self.tableView reloadData]:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(doUpdateAppBefore:) name:UIApplicationWillEnterForegroundNotification object:nil];
Also I'm reloading data of tableView on every UIApplicationBecomeActive notification.
Before I close my app and open it up from background to find out if it's reloads the data, I'm moving to another UIViewController and going back, which causes that somehow identifier of my self.tableView changes. I'm checking it in:
NSLog(#"Calling reloadData on : %#");
and at the beginning it gives me:
Calling reloadData on <UITableView: 0x9b09400;....
but after I segue back from another UIViewController it gives me:
Calling reloadData on <UITableView: 0x9b4b000;
which causes that it doesn't actually reload the data after I open up the app from the background state.
I've been thinking... when I segue back from another viewcontroller, viewDidLoad fires again, is it possible that it somehow sets tableView.delegate again and changes something? Just thinking...
Thank you very much for your answers.
It sounds like you have a view controller, push a modal view on top of it, and then want to go back to the original view controller when you're done. So, you set up a modal segue in your storyboard, and then a second modal segue to go back. The problem is that your second modal segue doesn't return to the original view controller, but it creates a new instance of that view controller, and now your have the original view controller, the second view controller, and an unwanted third view controller. Instead of creating a segue, which creates the third view controller, you need to dismiss the second view controller, which then gets you back to your original view controller, and therefore also your original table view. So what you want to do is get rid of the second segue and replace it with an IBAction, put something like
- (IBAction)goBack:(id)sender;
in your .h file. Connect that to your button or whatever you're using to trigger the segue now. Then, in your implementation file, dismiss the modal view like so:
- (IBAction)goBack:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
That should get you what you want.
Alternately, and this is probably better, you can use an unwind segue as well. Go to List.h, and create this method:
- (IBAction)unwind:(UIStoryboardSegue *)segue;
Then just implement it, you can leave it blank for now. Then, drag from the button that currently triggers the segue to Exit, and select the Action Segue unwind. That will also get you back.

pop and refresh viewcontroller

I have three viewcontroller. when I get to the third viewcontroller, I use poptorootviewcontroller to pop to my first view controller, but when I use popviewcontroller in my third viewcontroller (i want to go back to my second viewcontroller) its poping but all the info that I edit in my second viewcontroller are there, and I want the secondviewcontroller to be new (reset this viewcontroller), like this viewcontroller to be reloaded.
here is my code in the third viewcontroller:
-(IBAction)playAgain:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
how can I do it?
thanks!
In the second viewcontroller, you should write a method viewWillAppear like below,
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//set initial values here
}
This method will call when your controller is about to appear. So while third viewcontroller will get popped, this method will get called and you can reset values.

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

How to scroll to a row in UITableView on first open

I have a UITableView which holds a number of choices and allows user to select one of these choices. I mark the selected row with a checkmark accessory.
On an iPad, I open this in a Pop over on click of a button and the table view shows up with one of the rows checked. But sometimes this checked row is not on screen and one needs to scroll to get to it. I would like to scroll to this checked row when I open the pop over. I have tried doing a scrollToRowAtIndexPath:atScrollPosition:animated: in viewDidAppear but I find that viewDidAppear is called before any call to cellForRowAtIndexPath and the scrolling to selected row doesn't happen
- (void)viewDidAppear:(BOOL)animated
{
NSLog(#"viewDidAppear called");
[super viewDidAppear:animated];
//currentSelectedIndexPath is a correct index path
[self.tableView scrollToRowAtIndexPath:currentSelectedIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
}
Try calling [self.tableView reloadData] just before scrolling in viewDidAppear.

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.