0
votes

I am following this forum: https://parse.com/questions/using-pfquerytableviewcontroller-for-uitableview-sections

If you go to the link above and read the title you will see that I am trying to create sections in my PFQueryTableViewController. After copying the code form the link above I was able to section my TableView just fine.. it works great! Here is my problem. (The best way to do this is to give an example). Imagine I have 3 sections of cells with 2 cells in each section

A B

C D

E F

When I click on A I get A result. When I click on B I get B result. But when I click on C I get A, and when I click on D I get B. Also When I click on E I get A and when I click on F I get B.

Basically it knows there are sections but it is making it as if there is 1 section that continuously repeats (3) times.

Here is the catch. The cells int he TableView display the correct information. It is after you click on the cells that the wrong information it transferred. Maybe I am missing something but I don't know where.

Here is my code:

@property (nonatomic, retain) NSMutableDictionary *sections;
@property (nonatomic, retain) NSMutableDictionary *sectionToSportTypeMap;

@implementation AllDataViewController
@synthesize sections = _sections;
@synthesize sectionToSportTypeMap = _sectionToSportTypeMap;

- (id)initWithCoder:(NSCoder *)aCoder
{
    self = [super initWithCoder:aCoder];
    if (self) {
        // Custom the table

        // The className to query on
        self.parseClassName = @"schedule";
        self.textKey = @"name";
        self.pullToRefreshEnabled = YES;

        self.paginationEnabled = YES;
        self.objectsPerPage = 25;
        self.sections = [NSMutableDictionary dictionary];
        self.sectionToSportTypeMap = [NSMutableDictionary dictionary];
    }
    return self;
}

- (PFQuery *)queryForTable
{
    PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];

    // If Pull To Refresh is enabled, query against the network by default.
    if (self.pullToRefreshEnabled) {
        query.cachePolicy = kPFCachePolicyNetworkOnly;
    }

    // If no objects are loaded in memory, we look to the cache first to fill the table
    // and then subsequently do a query against the network.
    if (self.objects.count == 0) {
        query.cachePolicy = kPFCachePolicyCacheThenNetwork;
    }


        [query orderByAscending:@"order"];

    return query;
}
- (void) objectsDidLoad:(NSError *)error
{
    [super objectsDidLoad:error];
    [self.sections removeAllObjects];
    [self.sectionToSportTypeMap removeAllObjects];

    NSInteger section = 0;
    NSInteger rowIndex = 0;
    for (PFObject *object in self.objects) {
        NSString *sportType = [object objectForKey:@"order"];
        NSMutableArray *objectsInSection = [self.sections objectForKey:sportType];
        if (!objectsInSection) {
            objectsInSection = [NSMutableArray array];

            // this is the first time we see this sportType - increment the section index
            [self.sectionToSportTypeMap setObject:sportType forKey:[NSNumber numberWithInt:section++]];
        }

        [objectsInSection addObject:[NSNumber numberWithInt:rowIndex++]];
        [self.sections setObject:objectsInSection forKey:sportType];
    }
}


- (PFObject *)objectAtIndexPath:(NSIndexPath *)indexPath {
    NSString *sportType = [self sportTypeForSection:indexPath.section];
    NSArray *rowIndecesInSection = [self.sections objectForKey:sportType];
    NSNumber *rowIndex = [rowIndecesInSection objectAtIndex:indexPath.row];
    return [self.objects objectAtIndex:[rowIndex intValue]];
}

#pragma mark - UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return self.sections.allKeys.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSString *sportType = [self sportTypeForSection:section];
    NSArray *rowIndecesInSection = [self.sections objectForKey:sportType];
    return rowIndecesInSection.count;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    NSString *sportType = [self sportTypeForSection:section];
    return sportType;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [super tableView:tableView didSelectRowAtIndexPath:indexPath];

    PFObject *selectedObject = [self objectAtIndexPath:indexPath];
}


- (NSString *)sportTypeForSection:(NSInteger)section {
    return [self.sectionToSportTypeMap objectForKey:[NSNumber numberWithInt:section]];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showDataDetail"]) { //showRecipeDetail

        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        //PFObject *selectedObject = [self objectAtIndexPath:indexPath];
        DataDetailViewController *destViewController = segue.destinationViewController;

        PFObject *object = [self.objects objectAtIndex:indexPath.row];
        AllData *data = [[AllData alloc] init];
        data.title = [object objectForKey:@"title"];
        data.imageFile = [object objectForKey:@"imageFile"];
        data.date = [object objectForKey:@"date"];
        data.information = [object objectForKey:@"information"];
        destViewController.data = data;

    }
}
2
Addition: I am pretty sure it has to do with prepareForSegue because when I Log didSelectRowAtIndexPath I get the right information. - Nicholas
Granted I didn't read through all of your code, but if it's happening in prepareForSegue and you have multiple sections but you're only segueing to the info in the first section, perhaps it is because of this line: PFObject *object = [self.objects objectAtIndex:indexPath.row]; where the object grabbed from the objects array is dependent solely on the row without regard for the section. So if row 1 in section 2 is selected, assuming your data is in a standard order, you'll still segue to row 1 in section 1. - Lyndsey Scott
I have more to write than will fit in the comment so I'll supply a proper answer... If I'm on the wrong track though, feel free to let me know. - Lyndsey Scott

2 Answers

0
votes

If you have multiple sections in your table, but you're only segueing to the info in the first section regardless of the section you've selected, perhaps it is because of this line:

PFObject *object = [self.objects objectAtIndex:indexPath.row];

where the object grabbed from the self.objects array is dependent solely on the row without regard for the section.

So as your code stands now, if row 1 in section 2 is selected, assuming your data is in a standard order (ex. A, B, C, D, etc), you'll still segue to row 1 in section 1. To get your code to work as intended, you may have to change this line:

PFObject *object = [self.objects objectAtIndex:indexPath.row];

to

PFObject *object = [self.objects objectAtIndex:indexPath.row * (indexPath.section + 1)];

such that you multiply by the (section + 1) to access the proper index in the self.objects array.

0
votes

Try nesting it an IF ELSE Statement like so

if (indexPath.section == 0) {
        //A
        if (indexPath.row == 0) {
            PFObject *object = [self.messagesArray objectAtIndex:indexPath.row];
        }
    }