This might be normal, but I'm new to objective-c.
I have an app with two view controllers, both are table views.
When a row is clicked, I load the second view to the top of the stack and pass a parameter through one of it's properties.
On the first view (loaded by default by the navigation controller) the viewDidAppear function is called first, it opens an XML file from a URL, builds an object for each node and pushes all the objects in to an array. After this is done, numberOfRowsInSection is called and it returns the count for the array and all is well.
On the other view, after it is loaded first the numberOfRowsInSection is called and then viewDidAppear. I'm really new to the iphone and I have no idea why this is even happening.
Thank you!
This is normal. viewDidAppear is called after the entire view is has finished loading and became visible.
This includes the UITableView. The Table View in turn requires the numberOfRowsInSection function to initialize.
You have three options to execute code before the UITableView loads:
1) Place your code in -viewWillAppear - this can occasionally be shaky
2) Subclass the UIViewController (chances are you are already doing this) and create a custom -init function to handle your setup
3) Put your initialization code inside of -numberofRowsInSection. This is always the first method of the UITableViewDataSource to be called. It is hackish but works very well in practice.
Maybe you should consider moving your code to -viewWillAppear or -viewDidLoad .
Thank you all for taking the time to reply!
I found the issue.
Being new to xcode/iphone/mvc, I forgot to connect the view to the IBOutlet object.
A few hours of my life I'll never get back.
Related
iOS newbie question: I have a UITableViewController with a navigation controller. I need to add an edit button to that controller. The table view controller is accessed from a tab controller. I have read several posts that suggest overriding the initWithNibName method. While this makes sense, I'm not understanding where/when this overridden method gets called or what I need to do force it to be called.
In other words, when I override this method, I get a successful build but the method never gets called and the code seems unreachable. What have I possibly left out?
Thanks!
if initWithNibName is not called, then your view controller is probably loaded from a storyboard file. In that case, you have to override initWithCoder: instead.
In the view controller that has a UITabBarItem, i realized that viewDidLoad() method only gets called the first time when the tab bar item is clicked. So I dont know how to bring up the dynamic graphics when it's clicked the 2nd time. Can some guru help me on this? thanks in advance.
Should I conform to some kind of delegates or should i do it within didSelectViewController method on the root controller of all the tab bars? If i do the later one, it just seems to be weird since i think the controller that has the corresponding tab bar item should render itself instead of doing the rendering on root controller..
You want to put any code that should run every time the view controller appears in viewWillAppear: instead of viewDidLoad. viewDidLoad is designed for code that should run when the view backed by your UIViewController is created (and then possibly re-created after being thrown away during low-memory situations).
Actually i resolved this by using the parameter passed into the callback didSelectViewController(param).
I've been following the guide in the following (StackOverflow question), which has been very helpful, and by completing the steps I've managed to successfully have a UITableView with a separate controller and delegate/datasource.
However, even though everything is working, I'm unable to reference or change anything instance of the UITableview.
For example: let's say the UIViewController for the table is TableViewController and the separate delegate/datasource class is TableDelegate. I have everything hooked up in interface builder as in the previous SO question. In TableDelegate.m, within viewDidLoad, I put the following:
self.navigationItem.leftBarButtonItem = self.editButtonItem;
And nothing changes in the UITableView as it should. This includes pushing UIViewControllers, which also has no effect as if the code wasn't even there, although when I NSLog(), it appears it is being run.
The odd part, however, is that even though that doesn't work, if I set the table's alpha property to 0, it works.
Thanks for any help in advance, let me know if you need any more information to solve the problem.
From your comments, it looks like both TableViewController and TableDelegate are subclasses of UIViewController. If this is the case, make sure both are being added to the navigation stack by pushing them onto a UINavigationController or adding them to a UITabBarController: otherwise, viewDidLoad may not be called.
As an aside, I don't think it's a good idea to have your UITableViewDataSource be a UIViewController subclass when you've already got a UITableViewController to handle that table view.
I'm developing a graphing application that on the main navigation/tab view displays a UIView that renders a graph using openGL. Beneath that view is a UITableView that displays the list of elements on the graph, and an add button.
Occasionally, when the user clicks on another tab, and then returns to the graph view tab, the table view does not get redrawn.
I have a [tableView reloadData] method being called in the navigation controllers' (also the table view's delegate and data source) viewDidAppear method.
numberOfSectionsInTableView and numberOfRowsInSection get called, but cellForRowAtIndexPath does not despite both latter methods returning positive values.
This is an intermittant problem, only happening some of the time, but it's not clear what (if anything) influences this.
Does anyone have any ideas?
[edit] Should just quickly add; clicking or otherwise interacting with the table view, whether faulted as described or not, ALWAYS causes it to be sucessfully redrawn.
[And again] A bit more information; when it faults as described, and calls the first two but not the cellforRowetc method, it seems to wait until the user interacts with the table before cellForRowetc is finally called (the first two methods are then not called) and is redrawn.
I had a UIActivityIndicator, started on a seperate thread, that showed when requests were being made to a web service. When the web service calls were completed, a notification was sent to the graph controller class to stop and hide the UIActivityIndicator. In this method, reloadData was being called on the table whether the view was visible or not, which seemed to be causing the problem.
The conclusion seems to be not to call reloadData on a table unless it's visible.
I was looking forward to find a cause for my application being crushed at some point and I found out that methods of UITableView are being called before or at the same time as viewWillAppear is called.
In viewWillAppear I have code that is initializing number of rows in each section but numberOfRowsInSection is being called before I finished setting up array that has amount of rows in each section.
I believe that viewDidLoad is not suitable in my case because it is being called only once after launching an application. Am I right? And I need to make my initialization function called each time a view appears on the screen.
How can I overcome this failure?
Thank you in advance.
Well, I think this 'problem' has to do with that there are multiple threads running taking care of the view and the UITableView.
The view calling this view could (before switching to this view) call a method on the View which gathers the data.
User pushed button
You fire a method on the destination view, gathering information
Switch to view
You could work with delegates to know when the destination view is ready loading the data you needed, so you can switch to that view then.
Hope this helps.
I think the right answer is that "[super viewWillAppear:animated]" will call UITableView's method.So it is necessary to put this code after the code that initialize the tableView.