What is the correct way of using NSDiffableDataSourceSnapshot and - (void)tableView:(nonnull UITableView *)tableView prefetchRowsAtIndexPaths:(nonnull NSArray<NSIndexPath *> *)indexPaths.
It seems that every time prefetch reloads table view, table view asks for more prefetching, after calling apply snapshot, creating infinite loop.
- (void)reloadViews {
//[self.tableView reloadData];
NSMutableArray *items = [NSMutableArray new];
for (TCHChannel* channel in self.channels) {
[items addObject:channel.sid];
}
if ([items count] == 0) {
return;
}
NSDiffableDataSourceSnapshot<ConversationSectionType*, NSString*> *snapshot =
[[NSDiffableDataSourceSnapshot<ConversationSectionType*, NSString*> alloc] init];
ConversationSectionType *main = [ConversationSectionType new];
main.section = kMain;
[snapshot appendSectionsWithIdentifiers:#[main]];
[snapshot appendItemsWithIdentifiers:items intoSectionWithIdentifier:main];
[self.diffDataSource applySnapshot:snapshot animatingDifferences:NO];
}
And here is prefetch method:
- (void)tableView:(nonnull UITableView *)tableView prefetchRowsAtIndexPaths:(nonnull NSArray<NSIndexPath *> *)indexPaths {
for (NSIndexPath *indexPath in indexPaths) {
TCHChannel *channel = [self channelForIndexPath:indexPath];
NSMutableSet *currentChannelIds = [NSMutableSet new];
for (ConversationListViewModelUpdateOperation *op in self.modelQueue.operations) {
[currentChannelIds addObject:[op channelId]];
}
if ([currentChannelIds containsObject:channel.sid]) {
continue;
}
NSParameterAssert(channel != nil);
ConversationListViewModelUpdateOperation *op = [[ConversationListViewModelUpdateOperation alloc] initWithChannel:channel cache:self.channelViewModelsCache];
op.completionBlock = ^{
dispatch_async(dispatch_get_main_queue(), ^(void){
[self reloadViews];
});
};
[self.modelQueue addOperation:op];
}
}
Model queue is just operation queue:
- (NSOperationQueue*)modelQueue {
if (_modelQueue == nil) {
_modelQueue = [[NSOperationQueue alloc] init];
_modelQueue.maxConcurrentOperationCount = 4;
}
return _modelQueue;
}
Is there a way to use prefetching with diffable data sources without apply asking for more indexes?
EDIT:
So calling reloadData in prefetch methods makes infinite loop.. According to https://andreygordeev.com/2017/02/20/uitableview-prefetching/
WARNING: do not call tableView.reloadData() or
tableView.reloadRows(...) from tableView(_ tableView: UITableView,
prefetchRowsAt indexPaths: [IndexPath]) method! These methods provoke
UITableView to call prefetchRowsAt... and thus lead to infinity loop.
Soo.. how has Apple intended for prefetching to be used with Diffable Data Sources? ... -.-
Related
News feed are not shown in table viewcontroller.BuyerSocialPage that is linked with Newsfeed Viewcontroller has BuyerSocialPage.h file
#interface BuyerSocialPage : UIViewController <UITableViewDataSource,UITableViewDelegate>
#end
#implementation BuyerSocialPage
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.tableView.delegate=self;
UINib * firstNib = [UINib nibWithNibName:#"BSPFirstCell" bundle:nil];
[self.tableView registerNib:firstNib forCellReuseIdentifier:#"BSPFirstCell"];
UINib * secondNib = [UINib nibWithNibName:#"BSPSecondCell" bundle:nil];
[self.tableView registerNib:secondNib forCellReuseIdentifier:#"BSPSecondCell"];
UINib * thirdNib = [UINib nibWithNibName:#"BSPThirdCell" bundle:nil];
[self.tableView registerNib:thirdNib forCellReuseIdentifier:#"BSPThirdCell"];
UINib * fourthNib = [UINib nibWithNibName:#"BSPFourthCell" bundle:nil];
[self.tableView registerNib:fourthNib forCellReuseIdentifier:#"BSPFourthCell"];
self.view.backgroundColor = [UIColor whiteColor];
[self getBuyerSocialPage];
if (self.revealViewController) {
[_sidebarButton addTarget:self.revealViewController action:#selector(revealToggle:) forControlEvents:UIControlEventTouchUpInside];
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
}
-(void)getBuyerSocialPage {
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
int row = (int)indexPath.row;
if (row == 0) {
return 324;
}
else if (row == 1)
{
return 152;
}
else if (row == 2)
{
return 152;
}
else
{
return 152;
}
}
#end
After login you will see home screen. From side menu bar at the top select the "news feed" and it should display the news feed.but it is not displaying newsfeeds.Api is running correctly on postman
How I can get news feed in the table view ?
Page Number is missing in your url &pageno=1.
Your url looks like this:
http://api.shoclef.com/api/NewsFeed?user_id=1164
It should be like this:
http://api.shoclef.com/api/NewsFeed?user_id=1164&pageno=1
try this in you API Manager class. Working fine for me.
NSString * url = [NSString stringWithFormat:#"%#NewsFeed?user_id=%I&pageno=1",API_BASE_URL,userID];
Update For Image
Update this code in your cellForRowAtIndexPath function in NewsFeedNew class
NSString *strUrl = [self.images objectAtIndex:indexPath.row].image;
strUrl = [strUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
[cell.image sd_setImageWithURL:[NSURL URLWithString:strUrl]];
You need to set tableview delegate and dataSource.
Also put a break point in numberOfRowsInSection method to verify that tableview is set with datasource and delegate.
You need to reload data of tableview when you get response - [self.tableView reloadData];
-(void)getBuyerSocialPage {
NSLog(#"getBuyerSocialPage");
UserDao * profileID = [[DatabaseManager sharedManager]getLoggedInUser];
ApiManager * manager = [ApiManager sharedManager];
[manager socialPageWithProfileID:profileID.userID withCompletionBlock:^(BOOL error, NSDictionary *socialPage) {
// NSMutableArray * details = [[NSMutableArray alloc]init];
for (NSDictionary * temp in socialPage ) {
[self.socialPageArray addObject:temp];
}
[self.tableView reloadData];
if (!error) {
self.profileImages=self.socialPageArray;
}
}];
}
Few things to debug here,
Your API response might be nil or having error check and log appropriate response.
If the server response is correct then get on the main thread and reload the TableView
Set the UITableViewDataSource and UITableViewDelegate to self if you haven't done in storyboard.
- (void)getBuyerSocialPage {
NSLog(#"getBuyerSocialPage");
UserDao *profileID = [[DatabaseManager sharedManager] getLoggedInUser];
ApiManager *manager = [ApiManager sharedManager];
__weak BuyerSocialPage *weakSelf = self;
[manager socialPageWithProfileID:profileID.userID withCompletionBlock:^(BOOL error, NSDictionary *socialPage) { [weak self]
if (error) {
NSLog("Error fetching data");
return;
}
for (NSDictionary *temp in socialPage ) {
[weakSelf.socialPageArray addObject:temp];
}
if ([weakSelf.socialPageArray count] > 0) {
// update UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.tableView.reloadData()
}
}
}]
}
When animating the deletion of all rows and hence the deletion of all sections that included all rows of a UITableView I am running into this error:
CRASH: attempt to delete row 2 from section 0, but there are only 0 sections before the update
In particular I have a singleton manager class that serves as the table view data source and delegate. I post an NSNotification to tell the table view to delete rows that should be deleted, and that NSNotification triggers the following method:
dispatch_async(dispatch_get_main_queue(), ^{
if ([[[Manager sharedManager] justDeletedIndices] count] > 0) {
[mainTableView beginUpdates];
NSMutableArray <NSIndexPath *> *pathsToDelete = [[Manager sharedManager] justDeletedIndices];
[mainTableView deleteRowsAtIndexPaths:pathsToDelete withRowAnimation:UITableViewRowAnimationFade];
[[Manager sharedManager] setJustDeletedIndices:[NSMutableArray new]];
[mainTableView endUpdates];
} else {
[mainTableView reloadData];
}
});
The code for the method is in turn triggered by a method in Manager like so:
- (void) deleteMessagesForNotificationObjects: (NSArray <Object *> *) objects {
// this is where the property that includes the NSIndexPath
[self p_updatePathsToDeleteForDeletedObjects:objects];
// this is the notification that should trigger the code above
[[NSNotificationCenter defaultCenter] postNotificationName:#"RefreshTableView" object:self];
// this is where I modify the underlying data structures that power
// the table view's data source
NSMutableArray *localObjects = [objects mutableCopy];
for (Object *obj in localObjects) {
[self deleteMessageWithToken:obj.token andUniqueID:nil andFireDate:obj.displayDate];
}
NSArray *allKeys = [self.displayDict allKeys];
NSMutableArray <NSString *> *keysToDelete = [NSMutableArray new];
for (NSString *key in allKeys) {
NSMutableArray <Object *> *currentArr = self.displayDict[key];
NSMutableArray <Object *> *objsToDelete = [NSMutableArray new];
for (int i = 0; i < [localObjects count]; i ++) {
if ([currentArr containsObject:localObjects[i]]) {
[objsToDelete addObject:localObjects[i]];
}
}
[currentArr removeObjectsInArray:objsToDelete];
[localObjects removeObjectsInArray:objsToDelete];
if ([currentArr count] < 1) {
[keysToDelete addObject:key];
}
}
[self.displayDict removeObjectsForKeys:keysToDelete];
self.keyOrder = [[[self class] orderedKeysFromDict:self.displayDict] mutableCopy];
}
I am unclear as to what has to happen in what order. How do the commands indicating to a table view that it has to delete certain rows in an animated fashion (discussed here: Add/Delete UITableViewCell with animation?) relate to the ordering of actually modifying the underlying data source? In what order do I (1) animate row deletion and section deletion and (2) actually delete those rows and sections?
The answer is that the data source has to be modified inside beginUpdates and endUpdates, not in another method or elsewhere in the code.
I have dropped my code into a situation where I need to call UITableView data source methods written in some UIViewController class before a particular view is presented so that the cells get prepopulated and I can set a BOOL that the data in the not present viewController class is valid or not. I may explain it in more detail if required, but I wanted to know if its possible to do that. If yes, then how to do it? .. as a particular set of my code written after [tableView reloadData] is dependent on running the dataSource methods of UITableView. Please throw some light on this, if needs to be handled in a specific thread?
Following is the case where I call reloadData. Note: This is happening in another class when basicFactsViewController's viewWillAppear method has not been called yet:
- (BOOL) isComplete {
dispatch_async(dispatch_get_main_queue(), ^{
[basicFactsViewController.tableView reloadData];
});
return basicFactsViewController.isComplete && selectedVehicleId && selectedMakeId && selectedModelId && selectedYearId && selectedTrimId;
}
Now basicFactsViewController.isComplete is checked in this method:
- (BOOL) isComplete {
[self collectKeyHighlights];
return _isComplete;
}
Now the dictionary "tableCells" in the method below uses the cells population to check whether all features have been completed or not:
- (NSDictionary *) collectKeyHighlights {
NSMutableDictionary *key_highlights_update = [NSMutableDictionary new];
NSMutableDictionary *cell_highlight_update = [NSMutableDictionary new];
if(visible_key_highlights.count == 0) _isComplete = YES;
_isComplete = YES;
__block NSMutableArray *reloadCellAtIndexPathSet = [[NSMutableArray alloc] init];
[visible_key_highlights enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSDictionary *feature = (NSDictionary *)obj;
UITableViewCell *cell = [self.tableCells objectForKey:[NSIndexPath indexPathForRow:idx inSection:0]];
if(cell) {
if([cell isKindOfClass:[DRColorSelectionTableViewCell class]]) {
NSInteger selectedIndex = ((DRColorSelectionTableViewCell *)cell).selectedIndex;
NSInteger numberOfSegments = ((DRColorSelectionTableViewCell *)cell).numberOfSegments;
if(selectedIndex > -1 ) {
NSArray *dataValues = [[visible_key_highlights objectAtIndex:idx] objectForKey:#"data_values"];
NSDictionary *colorData;
BOOL reloadCellForIndexPath = NO;
if (numberOfSegments == selectedIndex) {
colorData = #{ #"normalized" : #"user_defined", #"isother" : #YES, #"hexcode":#"#FFFFFF", #"actual":((DRColorSelectionTableViewCell *)cell).otherColorTextField.text};
reloadCellForIndexPath = YES;
}
else{
colorData = [dataValues objectAtIndex:selectedIndex];
}
[key_highlights_update setObject:colorData forKey:[feature objectForKey:#"name"]];
[cell_highlight_update setObject:colorData forKey:[feature objectForKey:#"name"]];
if (![colorData isEqual:[prevSelections objectForKey:[feature objectForKey:#"name"]]]) {
[reloadCellAtIndexPathSet addObject:((DRColorSelectionTableViewCell *)cell).indexPath];
}
//if (reloadCellForIndexPath) {
//}
} else {
_isComplete = NO;
}
} else if([cell isKindOfClass:[DRInputTableViewCell class]]) {
NSString *textInput = ((DRInputTableViewCell *)cell).inputTextField.text;
if([textInput length]) {
[key_highlights_update setObject:[NSString toSnakeCase:textInput] forKey:[feature objectForKey:#"name"]];
[cell_highlight_update setObject:textInput forKey:[feature objectForKey:#"name"]];
}else {
_isComplete = NO;
}
} else if([cell isKindOfClass:[DRPickerTableViewCell class]]) {
NSString *textInput = ((DRPickerTableViewCell *)cell).inputField.text;
if([textInput length]) {
[key_highlights_update setObject:[NSString toSnakeCase:textInput] forKey:[feature objectForKey:#"name"]];
[cell_highlight_update setObject:textInput forKey:[feature objectForKey:#"name"]];
} else {
_isComplete = NO;
}
} else if([cell isKindOfClass:[DRSwitchTableViewCell class]]) {
// send this everytime for now
BOOL isSelected = ((DRSwitchTableViewCell *)cell).toggleButton.selected;
[key_highlights_update setObject:[NSNumber numberWithBool:isSelected] forKey:[feature objectForKey:#"name"]];
[cell_highlight_update setObject:[NSNumber numberWithBool:isSelected] forKey:[feature objectForKey:#"name"]];
}
}
else{
_isComplete = NO;
}
}];
prevSelections = cell_highlight_update;
if ([reloadCellAtIndexPathSet count]) {
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:reloadCellAtIndexPathSet withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
return key_highlights_update;
}
Now here since
[tableView reloadData]
is not calling cellForRowAtIndePath:, hence, tableCells is not getting populated, hence, I am always getting _isComplete = NO.
If I understand correctly, there is processing being done when the tableview loads (calls it's dataSource methods) and you want to trigger that early to use its results. Calling [basicFactsViewController.tableView reloadData]; early won't work if the basicFactsViewController hasn't been displayed yet. If basicFactsViewController is a UIViewController and has the default view and the tableView property is a subview of that standard view, then (if I remember correctly) the tableView property will be nil until the basicFactsViewController has been displayed. A shortcut around that is to access the viewController's view property and cause it to initialize (viewDidLoad and all that). You can do that by simply messaging the viewController: [basicFactsViewController view].
If I've been right so far I'm fairly confident that will initialize the tableView property. But I'm not sure if it will cause the table view to load its data. And even if it does work, it's definitely not the best solution to the piece of code you're trying to architect. Apple's design for UIKit has been focused on the model/view/controller pattern and it's easier to go with the flow and do the same. I imagine that you could move the processing that is in the data source methods for the tableView out into another class (or maybe even the same class), and call that method to get everything ready for both the tableView and any other checks that you have, storing the data in dictionaries and arrays in such a way that you can easily load them by index into the tableView when cellForIndex is called.
I have a UITableView that uses paging. All the delegates, and datasource are set.
My table view fetches a list of ten cars over the network and displays them by sending a page number (currentPage). During this fetch request I also get the pageCount which is the number of pages that contains cars on the server. Each page contains 10 cars.
I create a loading cell on the row that equals self.allCars.count which is my car array. This cell then fetches the next ten, and adds them to the self.allCars.count array. A loading cell is then created again for self.allCars.count + 1 etc. (I hope you get the picture, if not please ask).
On first launch the list contains All Cars which is the default request. However, the user can change it from a drop down. For example, they can select Blue Cars. This is passed into the fetchCars methods as the params parameter.
There is an unwanted behaviour in my code however: When I scroll down through the list, with the default paramter selected, and I scroll down three pages (three network calls to fetchCars...) and the array now contains 30 cars displayed in the tableView. However I now want to start a different search from scratch, so I go to the drop down, and select to filter by only blue cars (donePickerBlue). This method removes all the car objects, sets the currentPage back to 1, calls the network for the blue cars, and reloads the data. The unwanted behaviour occurs here. Because there had been 30 cells/indexPath.rows, the network call is called 3 times. This is because the indexPath.row < self.allCars.count is not true. This is where I am stuck, I can't seem to figure out how to fix it, so that if the search parameter is change (blue in this case) that it should treat it as new, I thought the [tableView reloadData] would handle this, but unfortunately it remembers how many index paths there are.
Its something i've been stuck on for a while. I've a feeling im missing something very simple to fix it.
Header file
#property (nonatomic) NSInteger currentPage;
#property (nonatomic) NSInteger pageCount;
Implementation
-(void)viewDidLoad{
...
self.currentPage = 1;
...
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (self.allCars.count ==0) {
return 0;
}
else{
if (self.currentPage<self.pageCount)
return self.allCars.count+1;
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell * cell = nil;
if (self.allCars.count!=0) {
if(indexPath.row <self.allCars.count){//here is where the problem occurs
cell=[self customCellForIndexPath:indexPath tableView:tableView];
}
else {
cell=[self loadingCell];
}
}
else{
// Disable user interaction for this cell.
cell = [[UITableViewCell alloc] init];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return cell;
}
-(UITableViewCell *)loadingCell{
UITableViewCell * cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
UIActivityIndicatorView * activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator.center = cell.center;
cell.backgroundColor = [UIColor lightGrayColor];
[cell addSubview:activityIndicator];
cell.tag=kLoadingCellTag;
[activityIndicator startAnimating];
return cell;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if (cell.tag==kLoadingCellTag) {
self.currentPage++;
[self performSelector:#selector(getCars:withParams) withObject:nil afterDelay:1.5f];
}
}
-(void)getCars{
[self getCars:url withParams:params];
}
-(void)getCars: (NSURL *)url withParams: (NSString *)params{
NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:0 timeoutInterval:80];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPMethod:#"POST"];
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.timeoutIntervalForResource=1;
NSURLSession * session = [NSURLSession sessionWithConfiguration:sessionConfig];
NSURLSessionDataTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response;
NSDictionary * dataDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
if (data) {
switch (httpResp.statusCode) {
case 200:{
dispatch_async(dispatch_get_main_queue(), ^{
self.pageCount = [dataDict[#"message"][#"total_pages"] intValue];
NSArray * carsArray = dataDict[#"message"][#"results"];
for (NSDictionary *cDict in carsArray) {
Car *car = [Car carWithID:[cDict[#"car_id"] stringValue] ];
car.car_name=cDict[#"car_name"];
car.car_description = cDict[#"car_description"];
[self.allCars addObject:car];
}
[self.tableView reloadData];
});
break;
}
default:
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Error");
});
break;
}
}
else{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Error");
});
}
}];
[task resume];
}
//reset list to start new search
-(void)donePickingBlue{
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
self.currentPage=1;
[self.allCars removeAllObjects];
[self getCars:url withParams:blue];
}
Edit
I seem to have resolved the the problem by doing the following;
//reset list to start new search
-(void)donePickingBlue{
self.currentPage=1;
[self.allCars removeAllObjects];
[self.tableView reloadData];//after removing all the cars, now we call reload, as there are no cars. I was calling reload in `[self getCars:....]` just below, and thought this was enough.
[self getCars:url withParams:blue];
}
I was able to answer my own problem. The answer can be seen in the Edit above incase anybody else has the same problem.
It should have been;
//reset list to start new search
-(void)donePickingBlue{
self.currentPage=1;
[self.allCars removeAllObjects];
[self.tableView reloadData];//after removing all the cars, now we call reload, as there are no cars. I was calling reload in `[self getCars:....]` just below, and thought this was enough.
[self getCars:url withParams:blue];
}
If you want to download cars page by page, willDisplayCell: is pretty good choice. But you must change the condition a little, to prevent downloading the same data multiple times. Also, I recommend you to change data model and provide ability to determine a page for particular cars. That's what I mean:
-(void)tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath{
// 10 cells on page
NSUInteger currentPage = indexPath.row / 10;
// Check, if cars for the current page are downloaded
if (carsOnPagesDict[#(currentPage)] != nil) {
// Add a stub to indicate that downloading started
// You can use this later to display correct cell
// Also it prevents getCars: from calling multiple times for the current page
carsOnPagesDict[#(currentPage)] = #"downloading";
// I removed delay for simplicity
[self getCars:url withParams:params forPage:currentPage];
}
}
Also, change getCars method:
-(void)getCars:(NSURL *)url withParams:(NSString *)params forPage:(NSUInteger)page{
// Creating request...
// ...
// Processing response...
// ...
// Array obtained:
NSArray *carsArray = dataDict[#"message"][#"results"];
// Storing required data to the array
NSMutableArray *cars = [NSMutableArray arrayWithCapacity:carsArray.count];
for (NSDictionary *cDict in carsArray) {
Car *car = [Car carWithID:[cDict[#"car_id"] stringValue] ];
car.car_name=cDict[#"car_name"];
car.car_description = cDict[#"car_description"];
[cars addObject:car];
}
// Save cars to the dictionary for the page given
carsOnPagesDict[#(page)] = cars;
// ...
// Resuming tasks...
}
You may consider using CoreData to store that cars.
In my firstViewcontroller , I build a tableview.Its data are coming from a data base.In secondviewcontroller I insert data in the database,and I call function from firsviewcontroller to build the dictionnary data as I did in firstviewcontroller to extract data .All data are recovered from database but the tableview can't be reladed.I have no access to cellForRowAtIndexPath even numberofrowsinsection>0
This what I did :
Secondviewcontroller:
//I insert data in database and I instanciate class where my tableview is and call refresh method
first = [[FirstviewController alloc]initWithNibName:#"FirstviewController" bundle:nil];
[first refreshList];
//in Firstviewcontroller
-(void)refreshList{
self.tableview= [[[UITableView alloc] initWithFrame:self.view.bounds] autorelease];
tableview.dataSource = self;
tableview.delegate = self;
NSMutableArray *array = [[NSMutableArray alloc] init];
//I recover my data from data base
IPADAGRIONEActivityList *arrayActivities = [IPADAGRIONEActivity findAll];
if ([arrayActivities length] > 0)
{
for (IPADAGRIONEActivity * oneRec in arrayActivities)
{
[array addObject:oneRec];
}
}
//activities is NSMutablearray that contains all my data
self.activities = array;
//I build dictionnary
[self buildObjectsDictionnary:activities
NSLog(#"self.act%#",self.tableview);
[array release];
[self.tableview reloadData];
}
//numberofrowsinSection:
NSLog(#"rows%d",[[objects objectForKey:[objectsIndex objectAtIndex:section]] count]);
return [[objects objectForKey:[objectsIndex objectAtIndex:section]] ;
//numberOfSection:
NSLog(#"nbre of section%d",[objectsIndex count]);
return [objectsIndex count];}
//CellforRowatInddexPath: It dosen't access to this method
if (cell== nil) {
cell = [[MHCActivityListCell alloc]init];
}
IPADAGRIONEActivity *activite ;
cell.activityCategory.text = [NSString stringWithFormat:#"%#", [activite EMAIL]];
}
}
It looks like self.tableView is not actually visible. You re-initialize it in refreshData but you do not add it as a subview again with [self.view addSubview:self.tableView].
As I said before, IT IS INCORRECT AND BAD USAGE to re-initialize the tableView, but it looks like thats the problem.
cellForRowAtIndexPath does not get called because the tableview is not visible so it doesn't try to display cells.