uicollectionviewcontroller ios objective-c pagination uicollectionview uipagecontrol

ios - uicollectionviewcontroller - uicollectionviewcell indexpath



UICollectionView: ruta de índice actual para control de página (5)

Estoy usando un UICollectionView con un diseño de flujo para mostrar una lista de celdas, también tengo un control de página para indicar la página actual, pero parece que no hay manera de obtener la ruta del índice actual, sé que puedo obtener celdas visibles:

UICollectionView índice de celda visible actual

sin embargo, puede haber más de una celda visible, incluso si cada una de mis celdas ocupa todo el ancho de la pantalla, si la desplazo para tener dos mitades de dos celdas, entonces ambas son visibles, por lo que hay una manera de obtener una índice de celda visible actual?

Gracias


  1. Coloque PageControl en su vista o establecido por Código.
  2. Establecer UIScrollViewDelegate
  3. En Collectionview -> cellForItemAtIndexPath (Método) agregue el siguiente código para calcular el Número de páginas,

    int pages = floor(ImageCollectionView.contentSize.width/ImageCollectionView.frame.size.width); [pageControl setNumberOfPages:pages];

  4. Agregue el método Delegado ScrollView ,

    #pragma mark - UIScrollVewDelegate for UIPageControl - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { CGFloat pageWidth = ImageCollectionView.frame.size.width; float currentPage = ImageCollectionView.contentOffset.x / pageWidth; if (0.0f != fmodf(currentPage, 1.0f)) { pageControl.currentPage = currentPage + 1; } else { pageControl.currentPage = currentPage; } NSLog(@"finishPage: %ld", (long)pageControl.currentPage); }


Definitivamente necesitas atrapar el elemento visible cuando se detiene el movimiento de desplazamiento. Usa el siguiente código para hacerlo.

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { if let indexPath = myCollectionView.indexPathsForVisibleItems.first { myPageControl.currentPage = indexPath.row } }


Obtener la página a través de NSIndexPath desde el centro de la vista.

Funciona incluso su página no es igual al ancho de UICollectionView.

func scrollViewDidScroll(scrollView: UIScrollView) { let center = CGPoint(x: scrollView.contentOffset.x + (scrollView.frame.width / 2), y: (scrollView.frame.height / 2)) if let ip = collectionView.indexPathForItemAtPoint(center) { self.pageControl.currentPage = ip.row } }


Puede obtener el índice actual supervisando contentOffset en scrollViewDidScroll delegate

será algo como esto

-(void)scrollViewDidScroll:(UIScrollView *)scrollView { NSInteger currentIndex = self.collectionView.contentOffset.x / self.collectionView.frame.size.width; }


Tuve una situación similar en la que mi diseño de flujo se estableció para UICollectionViewScrollDirectionHorizontal y estaba usando el control de página para mostrar la página actual.

Lo logré utilizando un diseño de flujo personalizado .

/ ------------------------ Archivo de encabezado (.h) para encabezado personalizado ---------------- -------- /

/** * The customViewFlowLayoutDelegate protocol defines methods that let you coordinate with *location of cell which is centered. */ @protocol CustomViewFlowLayoutDelegate <UICollectionViewDelegateFlowLayout> /** Informs delegate about location of centered cell in grid. * Delegate should use this location ''indexPath'' information to * adjust it''s conten associated with this cell. * @param indexpath of cell in collection view which is centered. */ - (void)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout cellCenteredAtIndexPath:(NSIndexPath *)indexPath; @end @interface customViewFlowLayout : UICollectionViewFlowLayout @property (nonatomic, weak) id<CustomViewFlowLayoutDelegate> delegate; @end

/ ------------------- Archivo de implementación (.m) para el encabezado personalizado -------------------

@implementation customViewFlowLayout - (void)prepareLayout { [super prepareLayout]; } static const CGFloat ACTIVE_DISTANCE = 10.0f; //Distance of given cell from center of visible rect static const CGFloat ITEM_SIZE = 40.0f; // Width/Height of cell. - (id)init { if (self = [super init]) { self.scrollDirection = UICollectionViewScrollDirectionHorizontal; self.minimumInteritemSpacing = 60.0f; self.sectionInset = UIEdgeInsetsZero; self.itemSize = CGSizeMake(ITEM_SIZE, ITEM_SIZE); self.minimumLineSpacing = 0; } return self; } - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; } - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSArray *attributes = [super layoutAttributesForElementsInRect:rect]; CGRect visibleRect; visibleRect.origin = self.collectionView.contentOffset; visibleRect.size = self.collectionView.bounds.size; for (UICollectionViewLayoutAttributes *attribute in attributes) { if (CGRectIntersectsRect(attribute.frame, rect)) { CGFloat distance = CGRectGetMidX(visibleRect) - attribute.center.x; // Make sure given cell is center if (ABS(distance) < ACTIVE_DISTANCE) { [self.delegate collectionView:self.collectionView layout:self cellCenteredAtIndexPath:attribute.indexPath]; } } } return attributes; }

Su clase que contiene la vista de colección debe cumplir con el protocolo ''CustomViewFlowLayoutDelegate'' que describí anteriormente en el archivo de encabezado de diseño personalizado. Me gusta:

@interface MyCollectionViewController () <UICollectionViewDataSource, UICollectionViewDelegate, CustomViewFlowLayoutDelegate> @property (strong, nonatomic) IBOutlet UICollectionView *collectionView; @property (strong, nonatomic) IBOutlet UIPageControl *pageControl; .... .... @end

Hay dos formas de conectar su diseño personalizado a la vista de colección, ya sea en xib O en el código, como por ejemplo en viewDidLoad:

customViewFlowLayout *flowLayout = [[customViewFlowLayout alloc]init]; flowLayout.delegate = self; self.collectionView.collectionViewLayout = flowLayout; self.collectionView.pagingEnabled = YES; //Matching your situation probably?

Por último, en el archivo de implementación de MyCollectionViewController, implemente el método delegado de ''CustomViewFlowLayoutDelegate''.

- (void)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout cellCenteredAtIndexPath:(NSIndexPath *)indexPath { self.pageControl.currentPage = indexPath.row;

}

Espero que esto sea de ayuda. :)