【问题标题】:How do I refresh a UICollectionView so it reflects the most recent changes made to my dataSource?如何刷新 UICollectionView 以反映对我的数据源所做的最新更改?
【发布时间】:2014-04-29 11:55:32
【问题描述】:

我正在应用中实现过滤器的功能,该过滤器使用商品的价格对商品进行排序。我想让客户能够使用 UIPickerView 按价格从高到低或从低到高对商品进行排序。

外观的想法:

问题:

我遇到的问题是在我查询了 parse.com 数据库并获得了新排序的数据之后,为我的 UICollectionView 重新加载数据没有任何效果。我觉得这很令人困惑,因为我正在更改我的实际数据源(存储数据库结果的 NSArray)。所以我在重新加载数据时收集了我的UICollectionView 将获取最新结果。但是什么也没发生。

我的设置如下:

跟踪 UIPickerView(过滤器)是否被激活:

@implementation VAGGarmentsCollectionViewController
{
    BOOL _filterActivated;
}

当点击过滤器打开 UIPickerView 时,将 _filterActivated 实例变量设置为 yes:

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

    _filterActivated = YES;
}

设置 UIPickerView 行的标题:

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

检测 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];
}

检测何时点击完成按钮:

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

    [_thisController performQuery];
    [_collectionView reloadData];

    _filterActivated = NO;
}

然后我有一个 performQuery 方法,它调用 queryForCollection 方法以在从 parse.com 在后台抓取数据之前采用任何其他查询选项

采集方式查询:

-(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;
}

执行查询方法:

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

分解一下我在做什么:

  • 检测 UIPickerView 已使用“filterButtonTapped”方法将“_filterActivated”实例变量设置为 yes。

  • 点击完成按钮时执行查询。 performQuery 方法调用 queryForCollection 方法。在该方法中,我检查“_filterActivated”是否设置为yes,如果是,然后检查UIPickerView 中的哪一行被选中,并将适当的查询选项添加到查询中。

  • 然后,我希望在 performQuery 方法完成后重新加载我的 UICollectionView 的数据。没发生什么事。我也尝试过重新加载可见项目和索引路径中的项目,但仍然一无所获。

也许我做错了。我睡在上面,想今天下午再试试,但还是看不出哪里出错了。

我想做的事:

我想要做的就是在UIPickerView 中选择一个过滤器选项/行(例如,从低到高排序的项目)并点击@ 的完成UIButton 之后重新加载整个UICollectionView 987654337@.

更新:

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

}

【问题讨论】:

  • 你是在成功回调中调用reloadData吗?
  • 不,在检测我的完成按钮何时被点击的方法中调用它。

标签: ios objective-c cocoa-touch uitableview uicollectionview


【解决方案1】:

您在请求新数据之后,但在实际接收到新数据之前调用 reloadData。

在 performQuery 返回并且在 pickerDoneButtonTapped 中调用 reloadData 之后,正在调用您传递给 findObjectsInBackgroundWithBlock 的块。

将reloadData 放在你传递findObjectsInBackgroundWithBlock 的块的末尾,或者放在objectsDidLoad: 方法中。

【讨论】:

  • 刚刚检查了我的 objectsDidLoad 方法,我已经在那里重新加载数据。
  • 是的,刚刚添加到帖子中。
  • 我看到我的代码现在在做什么。我删除了 _filterActivated 因为它不是必需的。推荐项目将默认显示。无论如何,当我在选择器中进行选择后点击完成按钮时,只会附加更多项目(以正确的排序顺序)但在已经存在的项目下方。这对于分页来说是可以的,但当我单击完成按钮时就不行了。当我这样做时,我需要刷新整个页面。 performQuery 的设置方式使这变得复杂。就好像它检测到正在使用分页一样,它在添加更多项目时会跳过一些项目,因此不会再次添加相同的项目。
猜你喜欢
  • 1970-01-01
  • 2019-05-06
  • 1970-01-01
  • 2014-03-10
  • 1970-01-01
  • 1970-01-01
  • 2010-10-15
  • 2013-08-22
  • 1970-01-01
相关资源
最近更新 更多