2012-10-01 63 views
10

Estoy utilizando un UICollectionView programmatically.UICollectionView con FlowLAyout no desplazándose al establecer secciones insertadas

he fijado que es el marco de la siguiente manera:

UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 3000) collectionViewLayout:flowLayout]; 

Mi UICollectionViewFlowLayout tiene una sección de inserción establecer como:

flowLayout.sectionInset = UIEdgeInsetsMake(20.0, 20.0, 100.0, 20.0); 

también sólo tengo 1 sección.

Establecí la altura en 3.000 para ver si la vista de colección se desplazaría pero no es así. Lo configuro porque la vista de la colección no parece desplazarse hacia arriba o hacia abajo cuando inserto elementos nuevos.

UICollectionView tiene una subclase de UIScrollView, lo que significa que puedo seguir restableciendo el tamaño del contenido de la vista de desplazamiento. ¿Funcionaría esto correctamente?

El único problema es que esto funcionaría si conozco los tamaños de todos los artículos, incluyendo cuántos elementos hay en cada fila.

Si cada artículo tuviera un tamaño diferente, ¿cómo averiguaría el tamaño de cada fila? Lo necesitaría para agregar todos los tamaños de fila y aumentar la altura del tamaño del contenido de self.collectionView.

EDITAR

Incluso mi sugerencia anterior, al restablecer el tamaño de contenido, no funciona correctamente! Intenté lo siguiente al actualizar mi vista de colección:

int numberOfRows = self.dataArray.count/3; 
self.collectionView.contentSize = CGSizeMake(self.view.frame.size.width, (numberOfRows * 200) + 300); 

Esto es muy feo. Esto es porque asume que todas mis imágenes son de tamaño 200x200px, que se ajusta a 3 imágenes por fila (de ahí la división por 3).

Además, incluso con el +300 que tengo, la última fila solo puedo ver 3/4 y no toda. Tengo que desplazarme más y podré verlo, pero vuelve a subir a 3/4. Es como el pergamino para refrescar, donde la vista solo se mueve si la arrastras y cuando la dejas regresa a donde estaba. ¿Por qué está pasando esto? ¿Es solo que Apple diseñó UICollectionView tan mal? Esto es un poco ridículo ... Las UITableViews ajustan su desplazamiento de acuerdo a su contenido automáticamente.

Respuesta

13

Al responder algunas de sus otras preguntas sobre UICollectionView, creé este proyecto de demostración, y se desplaza muy bien, así que no sé qué problema está teniendo. Lo único que tenía que hacer para hacer que la última fila fuera totalmente visible era aumentar el tamaño del recuadro inferior a 90. También agregué un método de finalización para performBatchUpdates: finalización: para desplazarme automáticamente de modo que esté visible el último elemento agregado (observe que agrego algunos elementos adicionales usando performSelector; withObject: afterDelay :). Mis imágenes son 48x48, y simplemente configuro mi vista de colección en los límites de la vista de mi controlador. Aquí está el código para que pueda compararlo con lo que tiene:

@interface ViewController() <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout> { 
NSMutableArray *newData; 
} 
@property (nonatomic, retain) UICollectionView *collectionView; 
@property (nonatomic, retain) NSMutableArray *results; 
@end 

@implementation ViewController 

- (void)viewDidLoad { 
    self.results = [NSMutableArray array]; 
    int i = 11; 
    while (i<91) { 
     UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"New_PICT00%d.jpg",i]]; 
     [self.results addObject:image]; 
     i++; 
    } 

    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; 
    //flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; 

    self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout]; 
    self.collectionView.dataSource = self; 
    self.collectionView.delegate = self; 
    self.view.backgroundColor = [UIColor blackColor]; 
    [self.view addSubview:self.collectionView]; 
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"]; 
    //[self.collectionView registerClass:[RDCell class] forCellWithReuseIdentifier:@"myCell"]; 
    [self.collectionView reloadData]; 

    [self performSelector:@selector(addNewImages:) withObject:nil afterDelay:3]; 
} 

-(void)addNewImages:(id)sender { 
    newData = [NSMutableArray array]; 
    int i = 102; 
    while (i<111) { 
     UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"New_PICT0%d.jpg",i]]; 
     [newData addObject:image]; 
     i++; 
    } 
    [self addNewCells]; 
} 

-(void)addNewCells { 
    NSMutableArray *arrayWithIndexPaths = [NSMutableArray array]; 
    [self.collectionView performBatchUpdates:^{ 
     int resultsSize = [self.results count]; 
     [self.results addObjectsFromArray:newData]; 
     for (int i = resultsSize; i < resultsSize + newData.count; i++) 
      [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]]; 
     [self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths]; 
    } 
    completion: ^(BOOL finished){ 
     [self.collectionView scrollToItemAtIndexPath:arrayWithIndexPaths.lastObject atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES]; 
    }]; 
} 


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

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

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath]; 
    //cell.iv.image = [self.results objectAtIndex:indexPath.row]; 
    cell.backgroundColor = [UIColor colorWithPatternImage:[self.results objectAtIndex:indexPath.row]]; 
    return cell; 
} 


- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { 
    UIImage *image = [self.results objectAtIndex:indexPath.row]; 
    return CGSizeMake(image.size.width, image.size.height); 
} 

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { 
    return UIEdgeInsetsMake(10, 10, 90, 10); 
} 

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 
    NSLog(@"Selected Image is Item %d",indexPath.row); 
} 
9

Ajuste de la altura de la UICollectionView a 3000 hacer su problema de desplazamiento peor. Si el UICollectionView tiene una altura de 3000 píxeles, solo necesitará desplazarse si tiene más de 3000 píxeles de contenido. Debes configurarlo a la altura de la vista en la que está contenido (igual que el ancho).

yo sepa el Tampoco se debe establecer el contentSize directamente, en lugar que necesita para reemplazar el método - (CGSize)collectionViewContentSize en una subclase de UICollectionViewLayout, pero en términos generales que no es necesario cambiar el tamaño del contenido para usos normales.

No tengo muy claro cuál es tu problema: ¿es que cuando agregas más de una pantalla con valor de elementos, no puedes desplazarte?

+0

Esta fue la solución para mí. Estaba usando un diseño de flujo personalizado que eliminó las brechas verticales entre los elementos en un diseño de varias columnas. Obtuve solo la mitad de los artículos hasta que hice lo que sugirió Simon. Sospecho que la razón por la que tuve el problema es que la cantidad de elementos consultados se basa en un diseño estándar. –

2

He encontrado el mismo problema porque estaba inicializando los elementos de mi collectionView (es decir, es DataSource) en el método viewWillAppear.

¡Finalmente agregué solo un [self.collectionView reloadData]; y funciona muy bien!

Quizás esté en el mismo caso.

Cuestiones relacionadas