UITableView not loading data the second time - ios4

I have a UITableView and I call reloadData in the viewWillAppear method
- (void)viewWillAppear:(BOOL)animated {
[tableView reloadData];
}
However, the second time my view appears, neither numberOfRowsInSelection nor cellForRowAtIndexPath are called
What could I be doing wrong?

I am seeing the same problem and yes, using a breakpoint I have already confirmed that viewWillAppear is called and reloadData executed - but cellForRowAtIndexPath is never called and the table contains stale data.
New information: I tried creating a new class/nib, this time using a UITableViewController instead of a UIViewController and implementing the delegate & datasource interfaces manually. This works as expected - cellForRowAtIndexPath is called and the table is updated. There must be something else UITableViewController does for me that I need to implement in my version, but I don't know what it is....

Solved! My issue, anyhow. I had wired up the datasource and controller connections, but hadn't connected the tableView outlet in my class to the table in the UI builder. smacks forehead. Mine works now, hope this helps!

Related

Receiver has no segue with identifier

I have a problem that I've been sitting with all the day. I have a super view which contains UIPageControl and UIScrollView, in this super view. I have created a sub view which contains three images, three labels, and three buttons. Each button has a touch up event. When the button event is triggered the super view will be promoted by a new view. For doing that, I created a segue which connected with super view and new view. Here is the connection code in the super view.
`
<connections>
<outlet property="pageControl" destination="ivy-0Q-UQo" id="rGm-sh-mdE"/>
<outlet property="scrollView" destination="4Yu-Qb-kbF" id="aqY-ou-cv4"/>
<segue destination="zZo-CH-P2Y" kind="push" id="xBU-ZO-u7s"/>
</connections>
`
This piece of code will guarantee the connection between the super view and the new view is okay,
here is the touch up event code.
WelcomeFrameViewController *welcomeFrameVC = [WelcomeFrameViewController alloc]; //super view instance
NSLog(#"=======================");
[welcomeFrameVC performSegueWithIdentifier: #"ForwardToLogin" sender: self];
When I run the program, the compiler complains with
2012-08-20 10:17:02.325 TTRen[2440:f803] ============44===========
2012-08-20 10:17:02.352 TTRen[2440:f803] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver WelcomeFrameViewController: 0x688e960 has no segue with identifier 'ForwardToLogin''
I am quite new in iOS, any suggestions will be deeply appreciated.
'Receiver WelcomeFrameViewController: 0x688e960 has no segue with
identifier 'ForwardToLogin''
In your storyboard, check that you actually have a segue named "ForwardToLogin"
There does seem to be a bug with xCode (still in 6) where storyboard changes you make aren't get copied to the simulator. You can reset the Simulator's Content & Settings to resolve this.
Other things to check:
Check the naming of your segue. Check it again. Check it some more :-)
Ensure that your segue is pointing in the right direction. It needs to point away from the UIViewController that calls performSegue….
Ensure you don't have two copies of your view controller on top of each other, with the segue attached to the one on top, and you instantiating the one underneath!
There's a similar question here and I encountered the same problem too. The reset fixed it for me.

Issue with Map view delegate method 'mapView:regionDidChange:' do not call

while using map view in my application some times MKMapKit delegate method 'mapView: regionDidChange' do not call.
Its happens only when I drag the map. but when i zoom in or Zoom out Its working perfectly. So its create issue related to place new annotations on map while dragging the map.
I have do this code in mapView:regionDidChange:
int j=0;
-(void) mapView:(MKMapView *)mapsView regionDidChangeAnimated:(BOOL)animated{
zoomLevel = self.mapView.region.span.latitudeDelta;
if (![appDelegate internetConnected]){
return;
}
if (appDelegate.isMapViewRegionChanged) {
if (j==0) {
j++;
return;
}else{
j=0;
appDelegate.isMapViewRegionChanged = FALSE;
return;
}
}
[self callGetMapViewWithObject:nil];
}
/*
first boolean is to check Internet connection.
[appDelegate internetConnected]
Second condition is to return when we navigate from any view controller too map View controller.
appDelegate.isMapViewRegionChanged
Third is a method to place new annotations.
[self callGetMapViewWithObject:nil];
*/
I checked all conditions and booleans but my coding is not reason for this bug.
so may be its related to region did change method.
So while using my app with map, 20% of time its behave like Ideal(method do not call).
can some one help me out with this.
Thank you in advance.
EDIT It broke randomly, so I now call the function again (undoing what I said below), no changes extra... and um, it works. I feel like I'm flipping a coin.
I just had this happen because I have a subclassed MKMapView. I don't know if you're subclassing this or not, but for some reason Apple's super functions, eg: -(void) scrollViewDidScroll; called super but was not intercepted properly and skipped that call.
When I removed the "overridden" call, that was just a call to [super scrollView], it started working properly.
I don't know why apple's code is broken that way (calling super doesn't have the same effect not overriding it), but make sure you're not subclassing these:
ScrollView functions
MKMapView functions...
or perhaps using the WildCard Gesture Recognizer provided very kindly by the answer to why Map Views don't respond to touchesBegan/Moved etc here: How to intercept touches events on a MKMapView or UIWebView objects? .
If this doesn't help, ensure you don't have a view on top of the other views, improper delegates, xibs are arranged and hooked up, the usual stuff.

Core Data: delay calling endUpdates till viewWillAppear

I have a Core Data app with a tab-bar controller that displays 2 view controllers. If I add something in the first tab's view controller, it should display in the 2nd tab's VC. Both VCs are based off a NSFetchedResultsController which is based off the same entity; the only difference is that one has a predicate and the 2nd VC doesn't.
This works fine for the normal template, and when data is added from the 1st VC, it gets updated instantly in the 2nd tab using controllerWillChangeContent and controllerDidChangeContent. The problem is that if the user adds or deletes any rows in the 1st VC, when the user comes to the 2nd tab they don't see the rows animatedly inserted or deleted... everything's already there.
What I would like to do, in the 2nd tab's VC, is delay calling the [self.tableView endUpdates] (which causes the animated inserting/deleting of rows in the table) till the user actually goes to that tab, in that VC's viewWillAppear. I've tried this, but doesn't seem to work:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
tableviewUpdates = TRUE;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (tableviewUpdates) {
tableviewUpdates = FALSE;
[self.tableView endUpdates];
}
}
This works if adding one row at a time and then switching to the 2nd tab, but not if I add multiple rows in the 1st tab and then switch.
Any help would be appreciated.
You're working against the purpose of the NSFetchedResultsController which is to make updating the tableview automatic and effortless.
I'm pretty sure, however, that if you override all the FRC delegate methods you can block all the automatic updates.
You might want to rethink this design. Are users really going to expect to see changes in one view reenacted in a second? Will they understand they are watching a rewind of the previous changes or will they intuitively think that the app is doing something to their data on its own?
The standard UI grammar teaches users to expect that one change animates once and then subsequently just shows up in a standard display. I would suggest you test this design with naive users carefully before deploying such a non-standard interface.

Getting UITabBarController to work with Core Data

I've been reading this thread on Stackoverflow and have been trying to replicate the solution with no success in my own project.
My project has 4 tabs. In my app delegate I do this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
Page1 *page1 = (Page1 *)[navController topViewController];
Page2 *page2 = (Page2 *)[navController topViewController];
Page3 *page3 = (Page3 *)[navController topViewController];
Page4 *page4 = (Page4 *)[navController topViewController];
page1.managedObjectContext = self.managedObjectContext;
page2.managedObjectContext = self.managedObjectContext;
page3.managedObjectContext = self.managedObjectContext;
page4.managedObjectContext = self.managedObjectContext;
[self.window makeKeyAndVisible];
return YES;
}
In the originating thread it says I need to create a IBOutlet to each navController for each tab I want to use Core data on.
Whilst you can assign multiple delegates for the UINavigationController the same is not true for the outlets, you can only ever supply ONE outlet for the navController.
I can get Page1 to work, but the other pages simply crash; because of the lack of an IBOutlet.
Do I really need X IBOutlets for Y Tabs or can I do it another way?
Another issue is that the originating thread the accepted answer is:
Ideally you want to pass either the
NSManagedObjectContext,
NSFetchedResultsController or the
relevant NSManagedObject "down" into
the UIViewController.
But there is no code or example of how to do this.
Ideally, I do not want to use a singelton or use the app delegate all over the place.
Any confirmation and clarification would be great.
Thanks.
Your immediate problem has nothing to do with Core Data. You are assigning the same navigation controller to each tab when you need a separate navigation controller for each tab otherwise the navigation controller's hierarchy of views will get scrambled every time you change tabs.
The pattern recommended in the question you linked to is called "dependency injection" and it is the one that Apple recommends in most cases. However, in the case of tabbars or any other complex view/view-controller hierarchy, dependency injection can get to complicated. It's a particular issue with tabbars because you don't usually load all tab view/view-controllers when the app starts but wait until each tab is selected before loading its elements.
Instead, you can use an alternative pattern that exploits the UIApplication objects singleton status. Since there is only one application object, there is only one application delegate object. That means that anywhere in the app you can make a call like this:
(MyApplicationDelegate *) appDelegate=(MyApplicationDelegate *)[[UIApplication sharedApplication] delegate];
... and always get the same application object. Then, if you have the managed object context defined as a property of the app delegate you can get the context just by:
theManagedObjectContext=appDelegate.managedObjectContext
Add these two lines to every view controller and you can always be sure of getting the app delegate's managed object context.

tableview methods are been called only Once in Objective C on iphones?

i have tableview.In method 'viewWillAppear',it calls a function and function data is stored in an array named 'list'.Now in the method 'numberOfRowsInSection' method it returns the list count...and in another method 'cellForRowAtInexPath' it displays data in cell...now when the view is pushed to the above view using pushViewnavigationcontroller,function is called in viewwillappear and data is shown in tableview..now when i come back to previous view and move to tableview view again...viewWillAppear method is called(i checked using NSLog)...but tableview displays the same previous data..that means methods numberOfRowsInSection,cellForRowAtIndexPath are called only Once at first click..why is it so??and what can be done to load the tableview again and again with changing values of the data..??
I found the solution by myself. Just use [tableview reloadData] in method viewWillAppear.

Resources