I have a UITableView instance tableView that displays data from a server.
The tableView will have to wait until the data is received, and then gets a call to it's reloadData method. All fine, works great.
Now I have a particular method that I want to perform right after the tableView finishes creating the first set of visibleCells. For this example I'll call the method performFancyActionOnVisibleCells. It seems however, that the reloadData action is asynchronous, so I can't just do
[tableView reloadData];
[self performFancyActionOnVisibleCells];
Because the visibleCells are still empty when that second line is executed, I will have to wait a bit before calling it. Which brings me to my question.
To my knowledge there is no delegate method like tableView:didFinishReloadingData. But if I'd want to call performFancyActionOnVisibleCells with the certainty that reloadData has finished updating the visibleCells property, where would that be?
Cheers,
EP.
To answer your question directly, I am not aware of any delegate callback for what you're looking for.
But, reloadData will call [tableView cellForRowAtIndexPath] on each of your visable rows so you could put a call at the bottom of that method.
I don't think that [tableView cellForRowAtIndexPath] gets called for every cell in your table but will get called by UIKit as required before the cell is made visable (for example, when scrolling).
Damien sounds right but I think that you should look at your strategy...Users may not be expecting something to popup (at a random time). I think you should display the cells first and then populate them. Use a progress indicator until the data has arrived. Then when the data arrives, draw it into the cell and thereafter you can run your fancyActionMethod. I hope this helps!
Related
Struggling to find where fault is with my code. On first view load, everything works and loads fine as it should, but when i revisit that view, it seems that the first two cells are empty. I logged the dictionary (dict) in viewWillAppear: and it logs the data fine, so error has to be in cellForRow method. Take a look at my method, and see where i'm going wrong, the third cell populate third piece of data, so i'm totally stumped, but the first two cells are completely blank, no data.
http://pastebin.com/Va84MG5g
First of all, why are you doing all of that insane UITableViewCell customization inside of your tableView:cellForRowAtIndexPath: method? Create a custom UITableViewCell subclass and do the set up there.
In the class's initWithStyle: method, add all of your subviews with a frame of CGRectZero, because at initialization, the table view cell doesn't know how big it is. You can set text alignments, colors, etc. here as well. Then, in layoutSubviews, go ahead and set all the frames. Override prepareForReuse and set things like your UIImageViews to nil. This will help with performance for reused cells.
As for why you're not seeing your data in your first two cells, my initial thought is that it has something to do with the way you're setting up your cells for reuse. You're asking your tableView to dequeue a regular UITableViewCell and only creating all of these subviews if the returned cell is nil. So what happens when it returns a UITableViewCell? You skip the part where you alloc/init all these subviews, and so you're basically adding nothing to the cell. I feel if you create a custom subclass and ask your UITableView to dequeue that instead, you'll get the result you're looking for.
NOTE: If you're targeting at least iOS 5, you can create your UITableViewCell's layout in a nib and register the nib with the table view. Doing so will guarantee that you always get a dequeued cell, and you never have to do your if (cell == nil) check. If you're targeting iOS 6, you can register a UITableViewCell subclass.
I'm working in Objective C. I have a UITableViewController with about 25 cells that push to a UIViewController. When the user hits back, I want to see if the user entered the correct data for the given cell. (I have a working bool , we'll call it isCellComplete for now). If isCellComplete is true, I want to add a checkmark as the accessory to the cell. I've been trying to put the test in cellForRowAtIndexPath but that method does not seem to run and refresh the cells everytime the view appears. Anyone have suggestions?
You should look into the UITableView method reloadRowsAtIndexPaths:withRowAnimation:. This is much more elegant than reloading the whole table view. And if you don't want an animation, you can specify UITableViewRowAnimationNone and it will look just like reloadData but be much more efficient.
You should do the check in tableView:cellForRowAtIndexPath: and if the check passes, set the cell's accessory to UITableViewCellAccessoryCheckmark. Then when you tell the table view to reload the appropriate row(s), it'll automatically call tableView:cellForRowAtIndexPath: on the data source and update that cell.
You could just call
[self.tableView reloadData];
in
-(void) viewWillAppear:(BOOL)animated
And that will make cellForRowAtIndexPath be called again when the view appears
I have UITableViewController where I need to put initialization code only once to populate data source. in which method to put this code.
I tried with viewWillAppear: method, but it get executed every time view appear.
if you want to display things only once that the View has comed on screen, then yeah. go for it. Otherwise you also have ViewdidLoad or ViewWillAppear if you have to arrange things before the view begins the transition to slide in.
All of these methods will be executed every time from the tableView you tap on a row.
anyway the pattern you are trying to achieve is called singleton, you can find out about it more over here
What should my Objective-C singleton look like?
You can put it in viewDidLoad and it will be only once.
The - (void)viewDidLoad method is probably the place you want use. It gets called once the view controller has finished doing its loading code (either by loading a XIB or by calling loadView).
Not sure how to ask this question so it will makes sense, but let me try. My app opens a UIViewController, and then calls another one. When it opens the other one it places a variable in a textfield successfully. When the user closes the 2nd UIViewController and returns to the 1st UIViewController, I pass back the variable and place it in a textfield. This is all successful at this point. The variable is being passed back and forth with no problems.
So here is what I am trying to do: upon returning to the 1st UIViewController I run a query statement which uses the variable in the textfield as a key to pull a record from a SQLite table. I use the NSLog to check the code and I see that the textfield is empty, but when the UIViewController appears the variable is in the textfield.
Are with me so far? I hope so…
I am running the query in the ViewDidLoad. I am thinking that the ViewDidLoad is running before it copies the variable from the 2nd into the textfield.
My main question is: should I be running my query statement in the ViewDidLoad or some please else to get the variable in the textfield. Basically, all I want to do is pull a record based on the value in the textfield upon returning from another UIViewController.
Thank You!
Technically, your viewDidLoad won't be called if your original view was never dealloced. The delegate methods that will be called are viewWillAppear: and viewDidAppear:.
You can pass the value from the second viewController back to the first one with a custom made delegate method. What you should keep in mind is that you should do the query with the NSString you pass back with the delegate method, and place it in the textField during viewWillAppear:.
Hope this helps!
viewDidLoad is only called when the view controller is loaded up from a nib. If you are switching back to one view controller from another, it won't be executed again. Try putting the code in viewWillAppear.
I update the UITableView's data source when viewDidAppear method is called on the ViewController that holds the tableview. So every time the user returns from the detailView the data is updated.
So the issue is that the UI is interrupted and the cell is selected until it is finished.
Is NSOperationQueue the best way to correct this?
Thanks for some suggestions.
Personally I would do these kind of things using either blocks or an NSOperation. The important thing is that the UI doesn't get blocked at any time if you can help it.