Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setCollectionViewLayout:animated causing debug error: Snapshotting a view that has not been rendered results in an empty snapshot

I am busy with UICollectionView in iOS7.

I am changing my collection view's layout between two different layouts. Which are a subclass of UICollectionViewFlowLayout.

This is how I change views when a button is tapped:

-(void)changeViewLayoutButtonPressed
{
    self.changeLayout = !self.changeLayout;

    if (self.changeLayout){
        [self.tableViewLayout invalidateLayout];
        [self.tradeFeedCollectionView setCollectionViewLayout:self.grideLayout animated:YES];

    }

    else {

        [self.grideLayout invalidateLayout];
        [self.tradeFeedCollectionView setCollectionViewLayout:self.tableViewLayout animated:YES];

    }
}

This method works as expected and the view is changed with a nice animation. However in the console I am receiving these messages:

Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.

Any ideas as to what is causing this?

like image 634
Robert J. Clegg Avatar asked Mar 17 '14 10:03

Robert J. Clegg


1 Answers

Just t expand on the comments above...

The strange thing about the warning I was getting was that my cv had three possible dataSources. All of them were basically the same data as: Collection 1, Collection 2, Collection 1 & 2.

When I was just viewing Collection 1 or Collection 2 I received no warnings. It was only when I was viewing the two combined I got warnings. The strange thing about this is there is less going on to show everything. Collection 1 and Collection 2 are extracted from the "Whole" so one extra step there. Not sure what this means.

Anyway I am no longer getting the messages.

Here's what I had originally:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [self arrangeCollectionView];
}

- (void)arrangeCollectionView
{
    UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)self.cv.collectionViewLayout;
    if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
    {
        flowLayout.sectionInset =  UIEdgeInsetsMake(16, 16, 16, 16);
        flowLayout.minimumInteritemSpacing = 16;
        flowLayout.minimumLineSpacing = 16;
    }
    else
    {
        flowLayout.sectionInset =  UIEdgeInsetsMake(26, 26, 26, 26);
        flowLayout.minimumInteritemSpacing = 26;
        flowLayout.minimumLineSpacing = 26;
    }
    self.cv.collectionViewLayout = flowLayout;    
}

And this was giving me the message on rotating to Landscape but not when rotating to Portrait.

Both of these changes resulted in no more messages:

1. Using

didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

to call arrangeCollectionView instead of

willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

Solved the warning problem but made the transition a bit cruder.

2. Getting rid of the explicit changes to the UICollectionViewFlowLayout and using the DelegateFlowLayout methods and calling reloadData from willAnimateRotation...:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [self.cv reloadData];
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize retval = CGSizeMake(172, 256);
    return retval;
}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
    return UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? UIEdgeInsetsMake(16 + 66, 16, 16, 16) : UIEdgeInsetsMake(26 + 66, 26, 26, 26);
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
    return UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? 16 : 28;
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
    return UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? 16 : 28;
}

This worked best for me. No more messages and a fairly smooth transition from one layout to the other.

Hope this helps you to track it down. I guess a screenshot is taken and presented to the user during the flow layout invalidation and this snapshot is being taken while at the same time the layout is already being reset in willRotate...... maybe anyway. Still not sure why I got constantly zero message for the 2 subsets of data and consistently always messages for the complete set.

Good luck, hope it helps.

like image 144
Bertie Avatar answered Oct 01 '22 14:10

Bertie