Vraag iOS6 UICollectionView en UIPageControl - Hoe zichtbaar cel te krijgen?


Bij het bestuderen van iOS6 nieuwe functies kreeg ik een vraag over UICollectionView.
Ik test het momenteel met de stroomlay-out en de schuifrichting ingesteld op horizontaal, scrollen en paging ingeschakeld. Ik heb de grootte ingesteld op exact dezelfde als de cellen van mijn aangepaste, zodat deze één voor één kan worden weergegeven en door deze opzij te schuiven, ziet de gebruiker de andere bestaande cellen.

Het werkt perfect.

Nu wil ik toevoegen en UIPageControl naar de verzamelweergave die ik heb gemaakt, zodat deze kan laten zien welke cel zichtbaar is en hoeveel cellen er zijn.

Het opbouwen van het paginabeheer was vrij eenvoudig, frame en numberOfPages gedefinieerd.

Het probleem dat ik ondervind, zoals de vraag titels markeert, is hoe je kunt krijgen welke cel momenteel zichtbaar is in de verzamelweergave, zodat deze de huidige pagina van het paginabesturingselement kan wijzigen.

Ik heb gedelegeerde methoden geprobeerd, zoals cellForItemAtIndexPath, maar het is gemaakt om cellen te laden, ze niet te tonen. didEndDisplayingCell triggert wanneer een cel niet meer wordt weergegeven, het tegenovergestelde geval van wat ik nodig heb.

Het lijkt erop dat -visibleCells en -indexPathsForVisibleItems, methoden voor het verzamelen van verzamelingen, de juiste keuze voor mij zijn, maar ik botste tegen een ander probleem. Wanneer moet ik ze activeren?

Alvast bedankt, ik hoop dat ik mezelf duidelijk genoeg heb gemaakt zodat jullie me kunnen begrijpen!


36
2017-11-01 11:44


oorsprong


antwoorden:


Je moet jezelf zo instellen UIScrollViewDelegate en implementeer de scrollViewDidEndDecelerating:methode zoals zo:

Doelstelling C

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    CGFloat pageWidth = self.collectionView.frame.size.width;
    self.pageControl.currentPage = self.collectionView.contentOffset.x / pageWidth;
}

Snel

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

    let pageWidth = self.collectionView.frame.size.width
    pageControl.currentPage = Int(self.collectionView.contentOffset.x / pageWidth)
}

91
2018-04-24 14:43



Ik heb hier ook een tijdje mee geworsteld en toen kreeg ik het advies om de bovenliggende klassen van UICollectionView te bekijken. Een van hen is toevallig UIScrollView en als je jezelf opricht als een UIScrollViewDelegate, krijg je toegang tot zeer nuttige methoden zoals scrollViewDidEndDecelerating, een geweldige plek om de UIPageControl bij te werken.


18
2017-11-10 04:14



Ik zou een beetje getunede berekening en afhandeling aanraden, omdat deze het paginabeheer onmiddellijk in elke schuifpositie met een betere nauwkeurigheid zal updaten.

De onderstaande oplossing werkt met elke scroll-view of subklasse (UITableView UICollectionView en anderen)

in viewDidLoad-methode schrijf dit

scrollView.delegate = self

gebruik dan de code voor uw taal:

Snel 3

func scrollViewDidScroll(_ scrollView: UIScrollView) 
    {
       let pageWidth = scrollView.frame.width
       pageControl.currentPage = Int((scrollView.contentOffset.x + pageWidth / 2) / pageWidth)
    }

Swift 2:

func scrollViewDidScroll(scrollView: UIScrollView) 
{
   let pageWidth = CGRectGetWidth(scrollView.frame)
   pageControl.currentPage = Int((scrollView.contentOffset.x + pageWidth / 2) / pageWidth)
}

Doelstelling C

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat pageWidth = self.collectionView.frame.size.width;
    self.pageControl.currentPage = (self.collectionView.contentOffset.x + pageWidth / 2) / pageWidth;
}

17
2018-05-08 13:08



Een andere optie met minder code is om het zichtbare itemindexpad te gebruiken en de paginabesturing in te stellen.

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    self.pageControl.currentPage = [[[self.collectionView indexPathsForVisibleItems] firstObject] row];
}

8
2018-05-20 21:00



  1. Plaats PageControl in uw mening of ingesteld door Code.
  2. set UIScrollViewDelegate
  3. In Collectionview-> cellForItemAtIndexPath (Methode) voeg de onderstaande toe code voor het berekenen van het aantal pagina's,

int-pagina's   = Vloer (ImageCollectionView.contentSize.width / ImageCollectionView.frame.size.width);       [pageControl setNumberOfPages: pages];

Voeg de toe ScrollView Delegate methode,

pragma mark - UIScrollVewDelegate voor 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);
}

5
2018-01-05 06:38



Ik weet dat dit een oude is, maar ik heb dit soort functies opnieuw moeten implementeren en heb een beetje toe te voegen wat een completer antwoord geeft.

Ten eerste: Gebruik makend van scrollViewDidEndDecelerating gaat ervan uit dat de gebruiker tijdens het slepen zijn vinger heeft opgetild (meer als een snelle actie) en daarom is er een fase van vertraging. Als de gebruiker sleept zonder de vinger op te tillen, wordt de UIPageControl zal nog steeds de oude pagina aangeven van voordat de sleep begon. In plaats daarvan de scrollViewDidScroll terugbellen betekent dat de weergave zowel na het slepen en vegen als tijdens het slepen en scrollen wordt bijgewerkt, zodat deze veel responsiever en nauwkeuriger voor de gebruiker aanvoelt.

Ten tweede: Zich baserend op de pagewidth voor het berekenen van de geselecteerde index wordt ervan uitgegaan dat alle cellen dezelfde breedte hebben en dat er één cel per scherm is. profiteren van de indexPathForItemAtPoint methode op UICollectionView geeft een veerkrachtig resultaat dat zal werken voor verschillende lay-outs en celgroottes. De onderstaande implementatie gaat ervan uit dat het midden van het frame de gewenste cel is die in de pagecontrol. Ook als er intercellafstanden zijn, zullen er tijden tijdens het scrollen zijn wanneer de geselecteerde Insdex nul of optioneel zou kunnen zijn, dus dit moet worden gecontroleerd en uitgepakt voordat het op de pagina Controle wordt ingesteld.

 func scrollViewDidScroll(scrollView: UIScrollView) {
   let contentOffset = scrollView.contentOffset
   let centrePoint =  CGPointMake(
    contentOffset.x + CGRectGetMidX(scrollView.frame),
    contentOffset.y + CGRectGetMidY(scrollView.frame)
   )
   if let index = self.collectionView.indexPathForItemAtPoint(centrePoint){
     self.pageControl.currentPage = index.row
   }
 }

Nog een ding - stel het aantal pagina's op de UIPageControl met zoiets als dit:

  func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    self.pageControl.numberOfPages = 20
    return self.pageControl.numberOfPages
  } 

4
2018-02-06 14:54



Simple Swift

public func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    pageControl.currentPage = (collectionView.indexPathsForVisibleItems().first?.row)!
}

UIScrollViewDelegate is al geïmplementeerd als u het implementeert UICollectionViewDelegate


3
2017-10-06 14:30