Подтвердить что ты не робот

IOS6 UICollectionView и UIPageControl - Как получить видимую ячейку?

При изучении новых функций iOS6 у меня возник вопрос о UICollectionView.
В настоящее время я тестирую его с помощью раскладки Flow и направления прокрутки, настроенного на горизонтальное, прокрутку и пейджинг. Я установил его размер точно так же, как и мои пользовательские ячейки, поэтому он может показывать по одному, а с помощью scrollig он боком, пользователь будет видеть другие существующие ячейки.

Он отлично работает.

Теперь я хочу добавить и UIPageControl в представление коллекции, которое я сделал, поэтому он может покажите, какая ячейка видна и сколько клеток есть.

Создание элемента управления страницы было довольно простым, определены кадры и числовые_файлы.

Проблема, с которой я сталкиваюсь, в качестве заголовков вопросов, заключается в том, как получить, какая ячейка в данный момент отображается в представлении коллекции, поэтому она может изменить текущий элемент управления страницей.

Я пробовал методы делегирования, например cellForItemAtIndexPath, но он сделан для загрузки ячеек, а не для их отображения. didEndDisplayingCell запускает, когда ячейка больше не отображается, противоположное событие того, что мне нужно.

Кажется, что -visibleCells и -indexPathsForVisibleItems, методы просмотра коллекции, являются правильным выбором для меня, но я столкнулся с другой проблемой. Когда запускать их?

Спасибо заранее, надеюсь, что я сделал себе достаточно ясно, чтобы вы, ребята, могли меня понять!

4b9b3361

Ответ 1

Вы должны настроить себя как UIScrollViewDelegate и реализовать метод scrollViewDidEndDecelerating: следующим образом:

Objective-C

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

Swift

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

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

Ответ 2

Я тоже боролся с этим, тогда мне посоветовали проверить родительские классы UICollectionView. Одним из них является UIScrollView, и если вы настроились на UIScrollViewDelegate, вы получаете доступ к очень полезным методам, таким как scrollViewDidEndDecelerating, отличное место для обновления UIPageControl.

Ответ 3

Я бы порекомендовал немного настроенный расчет и обработку, поскольку он будет обновлять контроль страницы сразу в любой позиции прокрутки с лучшей точностью.

Решение ниже работает с любым видом прокрутки или подкласса (UITableView UICollectionView и другие)

в режиме viewDidLoad напишите это

scrollView.delegate = self

затем используйте код для вашего языка:

Swift 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)
}

Цель C

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

Ответ 4

Другим вариантом с меньшим количеством кода является использование пути индекса видимого элемента и установка элемента управления страницы.

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

Ответ 5

  • Поместите PageControl в свое представление или задайте с помощью кода.
  • Установить UIScrollViewDelegate
  • В Collectionview → cellForItemAtIndexPath (Method) добавьте ниже код для расчета количества страниц,

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

Добавьте метод ScrollView Delegate,

знак прагмы - UIScrollVewDelegate для 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);
}

Ответ 6

Я знаю, что это старый, но мне просто нужно было снова реализовать эту функцию и немного добавить, что дает более полный ответ.

Во-первых: Используя scrollViewDidEndDecelerating, предполагается, что пользователь поднял палец во время перетаскивания (что больше похоже на действие щелчка), и поэтому существует фаза замедления. Если пользователь перетягивает, не поднимая палец, UIPageControl будет показывать старую страницу до начала перетаскивания. Вместо этого использование обратного вызова scrollViewDidScroll означает, что представление обновляется как после перетаскивания, так и при перемещении, а также во время перетаскивания и прокрутки, поэтому он чувствует себя намного более отзывчивым и точным для пользователя.

Во-вторых:. Полагаясь на pagewidth для вычисления выбранного индекса, предполагается, что все ячейки имеют одинаковую ширину и что на экране есть одна ячейка. использование метода indexPathForItemAtPoint на UICollectionView дает более устойчивый результат, который будет работать для разных макетов и размеров ячеек. В приведенной ниже реализации предполагается, что центр кадра представляет собой желаемую ячейку, которая будет представлена ​​в pagecontrol. Кроме того, если есть промежутки между ячейками, время будет прокручиваться, когда selectedIndex может быть нулевым или необязательным, поэтому это необходимо проверить и развернуть перед настройкой на страницеControl.

 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
   }
 }

Еще одна вещь - установите количество страниц в UIPageControl примерно так:

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

Ответ 7

Простая скорость

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

UIScrollViewDelegate уже реализован, если вы реализуете UICollectionViewDelegate