Question

When I perform [self.collectionView reloadData];, only my first item is reloaded.

Even though - (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section; is called and stores, for example, two items, then (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath is only called once for the first item.

I have verified that in numberOfItemsInSection the bounds are frame's sizes are big enough to store at least three of my items.

numberOfItemsInSection:2 frame: {{0, 0}, {400, 150}} and bounds {{0, 0}, {400, 150}}

And every UICollectionViewCell is {0, 0}, {400,45} and are stored vertically, as specified in the init method.

I have read there are several bugs with UICollectionView and ios7 but none of the previously described solutions worked for my case. I have already tried with reloadItemsAtIndexPaths and reloadSections but that did not work and sometimes gave me exceptions.

I have also tired to programatically add the items with no success:

[self.collectionView insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:   (self.currentPeripherals.count -1) inSection:0]]];

This is how my UICollectionViewController looks like:

- (instancetype)init
{
    UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init];
    [aFlowLayout setItemSize:CGSizeMake(400, 150)];
    [aFlowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
    self = [self initWithCollectionViewLayout:aFlowLayout];
    if (self) {
        self.view.frame=CGRectMake(0,0,400,150);
        self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        self.collectionView.backgroundView=[[UIView alloc] initWithFrame:CGRectZero];;
        self.view.layer.backgroundColor=[UIColor clearColor].CGColor;
        self.collectionView.backgroundColor=[UIColor clearColor];
        self.collectionView.delegate = self;
        self.collectionView.dataSource = self;
    }
    return self;
}

- (void)sharedInit {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleBTPOSHostDidUpdatePeripheralsNotification:) name:BTPOSHostDidUpdatePeripheralsNotification object:nil];
}

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section
{
    return self.currentPeripherals.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    DeviceCell *deviceCell = [cv dequeueReusableCellWithReuseIdentifier:CellID forIndexPath:indexPath];

    if(!deviceCell.label)
    {
        [deviceCell prepareForReuse];
        PeripheralTracking *peripheral=self.currentPeripherals[indexPath.item];
        [deviceCell configureLabelWithPeripheralTracking:peripheral forItem:indexPath.item];
        [deviceCell.contentView addSubview:deviceCell.label];
    }

    return deviceCell;
}

- (void)handleBTPOSHostDidUpdatePeripheralsNotification:(NSNotification *)notification
{
    NSUInteger oldCount = self.currentPeripherals.count;

    NSDictionary *trackedPeripherals = notification.userInfo[BTPOSHostDidUpdatePeripheralsNotificationPeripheralsKey];
    [self sortPeripheralsDictionary:trackedPeripherals];
    [self.collectionView reloadData];
}

And this is how my peripheral devices are sorted:

-(void)sortPeripheralsDictionary:(NSDictionary*)peripheralsDictionary
{
    NSMutableArray *dictValues = [[peripheralsDictionary allValues] mutableCopy];

    if(dictValues.count>1)
    {
        [dictValues sortUsingComparator: (NSComparator)^(PeripheralTracking *a, PeripheralTracking *b)
         {
             NSNumber *RSSI1 = 0;
             NSNumber *RSSI2 = 0;
             NSComparisonResult result = 0;

             if(a.averageRSSI)
             {
                 PeripheralTrackingRSSI doubleRSSIa = a.averageRSSI;
                 RSSI1 = [NSNumber numberWithDouble:doubleRSSIa];
             }
             if(b.averageRSSI)
             {
                 PeripheralTrackingRSSI doubleRSSIb = b.averageRSSI;
                 RSSI2 = [NSNumber numberWithDouble:doubleRSSIb];
             }

             if(RSSI1 && RSSI2)
             {
                 result = [RSSI2 compare:RSSI1];
             }

             return result;
         }
         ];
    }

    self.currentPeripherals = dictValues;
}
Was it helpful?

Solution

You're setting the height of each cell to 150:

[aFlowLayout setItemSize:CGSizeMake(400, 150)]

Try changing that to 45:

[aFlowLayout setItemSize:CGSizeMake(400, 45)]

Or you can implement collectionView:layout:sizeForItemAtIndexPath: if your cell size varies from cell to cell. The reason you're only seeing one call to collectionView:cellForItemAtIndexPath: is that your collection view only has room to display one cell. If you scroll it, you should see the other one.

OTHER TIPS

Try using this :

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
 {
   KKMDeviceCell *deviceCell = [cv dequeueReusableCellWithReuseIdentifier:kCellID forIndexPath:indexPath];

    if(!deviceCell.label)
     {
       [deviceCell prepareForReuse];

        [deviceCell.contentView addSubview:deviceCell.label];
     }

        PeripheralTracking *peripheral=self.currentPeripherals[indexPath.item];
        [deviceCell configureLabelWithPeripheralTracking:peripheral forItem:indexPath.item];
   return deviceCell;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top