Вопрос

I'm implementing the functionality for a filter in an app that sorts items using their price. I'm wanting to give a customer the ability to sort items by price high to low or low to high using a UIPickerView.

Idea of how it looks:

enter image description here

The issue:

The problem I'm having is after I have queried the parse.com database and have my newly sorted data, reloading the data for my UICollectionView has no effect. I find this confusing because I'm making changes to my actual dataSource (The NSArray where results from the database are stored). So I gathered upon reloading the data my UICollectionView would grab the latest results. Nothing happens though.

Here's how I'm set up:

To keep track of whether the UIPickerView (filter) was activated:

@implementation VAGGarmentsCollectionViewController
{
    BOOL _filterActivated;
}

When filter is tapped to open up UIPickerView set _filterActivated instance var to yes:

- (void)filterButtonTapped
{    
    // I have all code in here to create the UIPickerView
    // Deleted it all to make the post clearer    

    _filterActivated = YES;
}

Set title of UIPickerView rows:

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    return [_filterPickerArray objectAtIndex:row];
}

- (void)loadTitleForIndex:(NSInteger)index
{
    if (index == 0) {
        [_filterButton setTitle:@"Recommend" forState:UIControlStateNormal];
    } else if (index == 1) {
        [_filterButton setTitle:@"What's New" forState:UIControlStateNormal];
    } else if (index == 2) {
        [_filterButton setTitle:@"High to Low" forState:UIControlStateNormal];
    } else if (index == 3) {
        [_filterButton setTitle:@"Low to High" forState:UIControlStateNormal];
    }
}

Detect selection of particular row in UIPickerView:

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    NSIndexPath *selectedObjectIndex = [_filterPickerArray objectAtIndex:row];
    NSInteger indexOfSelectedObject = [_filterPickerArray indexOfObject:selectedObjectIndex];

    //Let's print in the console what the user had chosen;
    NSLog(@"Chosen item: %@", [_filterPickerArray objectAtIndex:row]);

    [_thisController loadTitleForIndex:indexOfSelectedObject];

    _selectedRowInFilterPicker = [_filterPicker selectedRowInComponent:0];
}

Detect when done button was tapped:

- (void)pickerDoneButtonTapped
{
    NSLog(@"Picker done button pressed");

    [_thisController performQuery];
    [_collectionView reloadData];

    _filterActivated = NO;
}

I then have a performQuery method that calls queryForCollection method to take on any additional query options before grabbing data in the background from parse.com

Query for collection method:

-(PFQuery *)queryForCollection
{
    PFQuery *query = [PFQuery queryWithClassName:@"Garments"];
    if (_filterActivated) {
        // check what the selectedRowInFilterPicker currently is
        // then add that task to the query
        NSLog(@"FILTER WAS ACTIVATED");

        if (_selectedRowInFilterPicker == 0) {

        } else if (_selectedRowInFilterPicker == 1) {

        } else if (_selectedRowInFilterPicker == 2) {
            NSLog(@"ORDER BY DESCENDING USING PRICE");
            [query orderByDescending:@"price"];
        } else if (_selectedRowInFilterPicker == 3) {
            NSLog(@"ORDER BY ASCENDING USING PRICE");
            [query orderByAscending:@"price"];
        }
    }
    return query;
}

Perform query method:

- (void)performQuery
{
    NSLog(@"PERFORM QUERY");
    PFQuery *query = self.queryForCollection;

    if (_paginationEnabled) {
        [query setLimit:_objectsPerPage];
        //fetching the next page of objects
        if (!_isRefreshing) {
            [query setSkip:self.objects.count];
        }
    }


    [self objectsWillLoad];

    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {


        self.isLoading = NO;
        if (error)
            self.objects = [NSArray new];
        else {
            if (_paginationEnabled && !_isRefreshing) {
                //add a new page of objects
                NSMutableArray *mutableObjects = [NSMutableArray arrayWithArray:self.objects];
                [mutableObjects addObjectsFromArray:objects];
                self.objects = [NSArray arrayWithArray:mutableObjects];
            }
            else {
                self.objects = objects;
            }
        }


        [self objectsDidLoad:error];
    }];
}

Break down of what I'm doing:

  • Detecting UIPickerView was activated using "filterButtonTapped" method to set the "_filterActivated" instance var to yes.

  • Performing query when done button is tapped. The performQuery method calls the queryForCollection method. In that method I check if "_filterActivated" is set to yes and if it is I then check to see which row in the UIPickerView was selected and add the appropriate query option to the query.

  • I then expect to have my UICollectionView's data reloaded once the performQuery method has finished. Nothing happens. I've tried reloading visible items and items at index path too and I still get nothing.

Maybe I'm going about this the wrong way. I slept on it and thought I'd try some more this afternoon but still can't see where I'm going wrong.

What I want to do:

All I want to do is have the whole UICollectionView reloaded after I've selected a filter option/row in the UIPickerView (e.g. items sorted from low to high) and tapped the done UIButton of the UIPickerView.

UPDATE:

- (void)objectsDidLoad:(NSError *)error
{
    _lastLoadedData = [NSDate date];
    [_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self.collectionView];
    [_loadingIndicator stopAnimating];
    [self.collectionView reloadData];

}
Это было полезно?

Решение

You're calling reloadData after requesting the new data, but before the new data has actually been received.

The block you pass to findObjectsInBackgroundWithBlock is being invoked after performQuery has returned and reloadData has been called in pickerDoneButtonTapped.

Put reloadData at the end of the block you pass findObjectsInBackgroundWithBlock, or in the objectsDidLoad: method.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top