Scroll UICollectionView自动滚动分页

Scroll UICollectionView自动滚动分页,scroll,uicollectionview,paging,Scroll,Uicollectionview,Paging,我的项目有一个UIcollectionView。这个水平分页和有四个对象。我想要我的收藏视图自动滚动页面。哪些使用方法?至于理论,我只是解释一下关键点。例如,如果您想在某处自动循环显示5幅图像,就像广告栏一样。您可以创建一个包含100个部分的UICollectionView,每个部分中有5个项目。创建UICollectionView后,将其原始位置设置为等于MaxSections的第50节第0项中间 这样您就可以向左或向右滚动。不要担心它会结束,因为我已经在计时器运行时将位置重置为MaxSect

我的项目有一个UIcollectionView。这个水平分页和有四个对象。我想要我的收藏视图自动滚动页面。哪些使用方法?

至于理论,我只是解释一下关键点。例如,如果您想在某处自动循环显示5幅图像,就像广告栏一样。您可以创建一个包含100个部分的UICollectionView,每个部分中有5个项目。创建UICollectionView后,将其原始位置设置为等于MaxSections的第50节第0项中间 这样您就可以向左或向右滚动。不要担心它会结束,因为我已经在计时器运行时将位置重置为MaxSections的中间位置。永远不要和我争论:当用户自己继续滚动时,它也会结束。如果发现只有5张图片,他会继续滚动吗!?我相信这个世界上很少有这样愚蠢的用户

注意:在以下代码中,headerView是UICollectionView,headerNews是数据。我建议将MaxSections设置为100

在自定义CollectionView之后添加NSTimer确保首先正确设置UICollectionViewFlowLayout:

    - (void)addTimer
    {
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:@selector(nextPage) userInfo:nil repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
        self.timer = timer;

}
然后实现@selectornextPage:

 - (void)nextPage
{
    // 1.back to the middle of sections
    NSIndexPath *currentIndexPathReset = [self resetIndexPath];

    // 2.next position 
    NSInteger nextItem = currentIndexPathReset.item + 1;
    NSInteger nextSection = currentIndexPathReset.section;
    if (nextItem == self.headerNews.count) {
        nextItem = 0;
        nextSection++;
    }
    NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:nextItem inSection:nextSection];

    // 3.scroll to next position
    [self.headerView scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
}
最后实现resetIndexPath方法:

- (NSIndexPath *)resetIndexPath
{
    // currentIndexPath
    NSIndexPath *currentIndexPath = [[self.headerView indexPathsForVisibleItems] lastObject];
    // back to the middle of sections
    NSIndexPath *currentIndexPathReset = [NSIndexPath indexPathForItem:currentIndexPath.item inSection:MaxSections / 2];
    [self.headerView scrollToItemAtIndexPath:currentIndexPathReset atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
    return currentIndexPathReset;
}
为了控制NSTimer,您必须实现一些其他方法和UIScrollView的委托方法:

- (void)removeTimer
{
    // stop NSTimer 
    [self.timer invalidate];
   // clear NSTimer
    self.timer = nil;
}

// UIScrollView' delegate method
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
        [self removeTimer];
}


- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
        [self addTimer];

}

至于理论,我只是解释了关键点。例如,如果您想在某处自动循环显示5幅图像,就像广告栏一样。您可以创建一个包含100个部分的UICollectionView,每个部分中有5个项目。创建UICollectionView后,将其原始位置设置为等于MaxSections的第50节第0项中间 这样您就可以向左或向右滚动。不要担心它会结束,因为我已经在计时器运行时将位置重置为MaxSections的中间位置。永远不要和我争论:当用户自己继续滚动时,它也会结束。如果发现只有5张图片,他会继续滚动吗!?我相信这个世界上很少有这样愚蠢的用户

注意:在以下代码中,headerView是UICollectionView,headerNews是数据。我建议将MaxSections设置为100

在自定义CollectionView之后添加NSTimer确保首先正确设置UICollectionViewFlowLayout:

    - (void)addTimer
    {
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:@selector(nextPage) userInfo:nil repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
        self.timer = timer;

}
然后实现@selectornextPage:

 - (void)nextPage
{
    // 1.back to the middle of sections
    NSIndexPath *currentIndexPathReset = [self resetIndexPath];

    // 2.next position 
    NSInteger nextItem = currentIndexPathReset.item + 1;
    NSInteger nextSection = currentIndexPathReset.section;
    if (nextItem == self.headerNews.count) {
        nextItem = 0;
        nextSection++;
    }
    NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:nextItem inSection:nextSection];

    // 3.scroll to next position
    [self.headerView scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
}
最后实现resetIndexPath方法:

- (NSIndexPath *)resetIndexPath
{
    // currentIndexPath
    NSIndexPath *currentIndexPath = [[self.headerView indexPathsForVisibleItems] lastObject];
    // back to the middle of sections
    NSIndexPath *currentIndexPathReset = [NSIndexPath indexPathForItem:currentIndexPath.item inSection:MaxSections / 2];
    [self.headerView scrollToItemAtIndexPath:currentIndexPathReset atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
    return currentIndexPathReset;
}
为了控制NSTimer,您必须实现一些其他方法和UIScrollView的委托方法:

- (void)removeTimer
{
    // stop NSTimer 
    [self.timer invalidate];
   // clear NSTimer
    self.timer = nil;
}

// UIScrollView' delegate method
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
        [self removeTimer];
}


- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
        [self addTimer];

}

@Elijah_Lam回答的Swift 2.0版本:

  func addTimer()
  {
    timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "nextPage", userInfo: nil, repeats: true)
    NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
  }

  func nextPage()
  {
    var ar = cvImg.indexPathsForVisibleItems()

    ///indexPathsForVisibleItems()'s result is not sorted. Sort it by myself...
    ar = ar.sort{if($0.section < $1.section)
      {
      return true
      }
      else if($0.section > $1.section)
    {
      return false
    }
      ///in same section, compare the item
      else if($0.item < $1.item)
      {
        return true
      }
      return false
    }


    var currentIndexPathReset = ar[1]
    if(currentIndexPathReset.section > MaxSections)
    {
      currentIndexPathReset = NSIndexPath(forItem:0, inSection:0)
    }

    cvImg.scrollToItemAtIndexPath(currentIndexPathReset, atScrollPosition: UICollectionViewScrollPosition.Left, animated: true)
  }

  func removeTimer()
  {
    // stop NSTimer
    timer.invalidate()
  }

  // UIScrollView' delegate method
  func scrollViewWillBeginDragging(scrollView: UIScrollView)
  {
    removeTimer()
  }


  func scrollViewDidEndDragging(scrollView: UIScrollView,
    willDecelerate decelerate: Bool)
  {
    addTimer()
  }

@Elijah_Lam回答的Swift 2.0版本:

  func addTimer()
  {
    timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "nextPage", userInfo: nil, repeats: true)
    NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
  }

  func nextPage()
  {
    var ar = cvImg.indexPathsForVisibleItems()

    ///indexPathsForVisibleItems()'s result is not sorted. Sort it by myself...
    ar = ar.sort{if($0.section < $1.section)
      {
      return true
      }
      else if($0.section > $1.section)
    {
      return false
    }
      ///in same section, compare the item
      else if($0.item < $1.item)
      {
        return true
      }
      return false
    }


    var currentIndexPathReset = ar[1]
    if(currentIndexPathReset.section > MaxSections)
    {
      currentIndexPathReset = NSIndexPath(forItem:0, inSection:0)
    }

    cvImg.scrollToItemAtIndexPath(currentIndexPathReset, atScrollPosition: UICollectionViewScrollPosition.Left, animated: true)
  }

  func removeTimer()
  {
    // stop NSTimer
    timer.invalidate()
  }

  // UIScrollView' delegate method
  func scrollViewWillBeginDragging(scrollView: UIScrollView)
  {
    removeTimer()
  }


  func scrollViewDidEndDragging(scrollView: UIScrollView,
    willDecelerate decelerate: Bool)
  {
    addTimer()
  }