VARUN ISAC
VARUN ISAC

Reputation: 443

UICollectionView refresh data

I am using a CollectionView which displays an array of objects. On clicking a button i fill this array with a new set of data. I want to refresh the CollectionView with this data. Is there any statement to update this instead of comparing each items and selectively deleting and adding? The reloadData usually ends up in the following error.

CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION

In Short, I am looking for the following steps... 1)Fill the datasource array, show the data. 2)Fill the datasource array with new data, refresh the CollectionView to show the data.

Thanks in Advance

Upvotes: 2

Views: 2638

Answers (2)

Ravi Tailor
Ravi Tailor

Reputation: 189

Suppose you arrive on your view then you can add data to your array in viewDidLoad method like so:

-(void)viewDidLoad
{
    [super viewDidLoad];

    // If you have already data 
    self.arr_sample=(NSArray *)array;     

     /* 
        When you want to download data from server than you have to call reloadData 
        method of collection because all delegate method already called before view load. 
        So loading data will take time to load data than you have to call all delegate 
        method of collectionview by calling reloadData method.
      */
    [self loadData];
    // Do any additional setup after loading the view from its nib.
}

but first of all you have set the delegate of collectionview . do you want to download data from server than you can call reloaddata method of collection view. such as

-(void)loadData
{
    // Do your downloading code her and call to reload data method of collectionview
    [collectionview reloadData];
}

now again do you want to refill your array with new data on your button click than you can do

-(void)refillData
{
    // Download new data code here and follow
    [array removeAllObjects];
    array=(NSArray *)newarray;
    [collectionview reloadData];
}

Upvotes: 0

greymouser
greymouser

Reputation: 3181

Try - (void)performBatchUpdates:(void (^)(void))updates completion:(void (^)(BOOL finished))completion.

In your case, you want "an all new set of data", so to speak, so e.g:

[myCV performBatchUpdates:^{
    // one of:
    // a)
    [myCV deleteSection:someIndexSetForTheEntireSection];
    [myRealDataSource empty:someIndexSetForTheEntireSection];
    //
    // OR b)
    [myCV deleteItemsAtIndexPaths:someSetOfIndexPaths];
    [myRealDataSource removeIndexPaths:someSetOfIndexPaths];

    // Either case:
    NSArray *indexPaths = [myRealDataSource getNewDataAndReturnIndexPaths];

    // if a)
    [myCV insertSections:newIndexSetForNewSection];

    // Either case:
    [myCV insertItemsAtIndexPaths:newIndexSetForInsertions];
}
completion:^(BOOL finished) {
    NSLog(@"Done.");
    // Maybe signal something else if you want.
}];

performBatchUpdates:completion: will expect the deletions & insertions from the original data source check entering the function to add up to the correct data source size leaving the method. It will loudly complain otherwise.

If you only have one section (section 0), you can be much more general than specific index paths if you are always "removing everything" and "inserting a complete new set".

Another option to to use KVO to listen on insertions and removals from the data source and simply reloadData, reloadItemsAtIndexPaths: or reloadSections: as appropriate.

I prefer the reactive KVO version, as I tend to use collection views with Core Data, and not pseudo-static or in-memory NSArray's.

To figure out the CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION issue, I'd setup a breakpoint on all exceptions, and try to discover what is really triggering the issue. Likely your datasource is gone and there's a bad access when you try to read/write from it.

Upvotes: 1

Related Questions