質問

Seriously frustrated trying to come up with a way to dynamic sort UICollectionView items.

The first time the UICollectionView is loaded, a different method to perform a query is run. This method only loads 4 items at a time and is always used with my pagination to load for 4. Setting up sorting with this was even more confusing because I was only able to sort 4 items at a time.

So I created another method to perform queries when trying to sort UICollectionView items.

I have a UIPickerView that allows customers to sort shopping items:

enter image description here

When done button is tapped a query parse.com is performed:

- (void)pickerDoneButtonTapped
{
    NSLog(@"Picker done button pressed");
     [_thisController performQueryForFilter];
}

It returns an NSArray of sorted objects depending on what row in picker was selected:

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

        if (_selectedRowInFilterPicker == 0) {
            NSLog(@"ORDER BY RECOMMENDED");
        } else if (_selectedRowInFilterPicker == 1) {
            NSLog(@"ORDER BY NEWEST ITEMS");
        } 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;
}

This is the performQueryForFilter method that is fired when done button it tapped:

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

    [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];
    }];
}

This is working correctly to an extent. I make a selection in the UIPickerView then top done. Now after the data in my UICollectionView has been reloaded I have 2 issues.

  • 1. The whole NSArray of correctly sorted objects is now the data for my dataSource so ALL of these objects are added to the UICollectionView after the reload of data.

  • 2. The previous cells that show by default when UICollectionView is first loaded still remain. So the newly sorted objects just added underneath.

Right now I have a maximum of 9 rows in my database. Now lets say in future there are 1000. I can't have 1000 rows being loaded and added to the UICollectionView every time a user wants to sort items with the option of low to high or high to low.

Please help me see where I'm going wrong or at least show a better way to do this.

役に立ちましたか?

解決

I think there is a misunderstanding here, either on your part about collection views, or on my part where your difficulty lies.

If I understand correctly, you fear that if you have an array of 1000 items, they would all be loaded into the collection view. This is not correct. Cells in the collection view are loaded dynamically and on demand. Whenever a cell is to be displayed, the data source is asked for the information for that cell. The information is never loaded all at once at any point. If you can display 8 cells at most on the screen, 8 cells are loaded at most in memory. That's it. When the user scrolls, the cells are recycled and used to display the next items, and so on.

So a few things. First, your optimization of paging the data is not necessary. If you need to load data in pages, you should provide the collection a number of items and then load and unload pages as the user scrolls. If the information is not big, you can load it all if possible. 1000 rows does not sound like a lot of information if the data is well normalized. Second, your query that returns 1000 items - fear not, the collection view will only load the necessary cells for what it can display and nothing more. It will reuse previous cells for data that follows.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top