以编程方式平滑滚动UIPageViewController

时间:2015-09-22 23:28:18

标签: ios performance animation scroll uipageviewcontroller

我的应用程序中有一个带有导航栏的UIViewController,如下面的gif所示。 UIViewController包含一个4页的UIPageViewController。导航栏上的每个选项卡代表UIPageViewController中的一个页面。

enter image description here

我正在尝试在这些UIPageViewController页面之间实现平滑滚动,即如果我当前在第一个选项卡上并单击导航栏上的最后一个选项卡,则UIPageViewController必须平滑地滚动所有选项卡到最后一个选项卡。虽然现在可行,但我对滚动性能不满意,因为它看起来很紧张。我正在使用

- setViewControllers:direction:animated:completion: api在页面之间滚动。

这是我的代码看起来像

- (void)navigateToNextPage {

    //you have navigated to the destination, return
    if(self.destinationPageIndex == self.currentPageIndex)
        return;

    if(self.destinationPageIndex < 0 || self.destinationPageIndex >= [self.pageViewControllerIdentifiers count])
        return;

    //determine the scroll direction
    UIPageViewControllerNavigationDirection direction = self.destinationPageIndex < self.currentPageIndex ? UIPageViewControllerNavigationDirectionReverse : UIPageViewControllerNavigationDirectionForward;

    //get the index of the next page to scroll  to
    NSInteger nextPageIndex = self.destinationPageIndex < self.currentPageIndex ? self.currentPageIndex-1 : self.currentPageIndex+1;

    //get the storyboard identifier of the page to navigate to
    NSString *identifier = [self.pageViewControllerIdentifiers objectAtIndex:nextPageIndex];
    NSString *storyboardName = @"Sales";
    id viewController = [COSCheckoutNavigationViewController instantiateControllerFromStoryboardName:storyboardName storyboardIdentifier:identifier];
    NSArray *viewControllers = @[viewController];

    __weak typeof (self) weakSelf = self;
    [self.pageViewController setViewControllers:viewControllers direction:direction animated:YES completion:^(BOOL finished) {
        [weakSelf updateCurrentPageIndex];

        //navigate to the next page after small delay
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [weakSelf navigateToNextPage];
        });
    }];
}

有没有办法可以改进此代码以获得更好的滚动性能?任何其他技术能否帮助我实现我所尝试的目标?

2 个答案:

答案 0 :(得分:0)

Swift 3.0.2

我遇到了和你一样的问题,我发现了一个适合我的解决方案。请记住,我使用childViewControllers管理UISegmentedControl。现在,我不允许滑动手势因为它弄乱了我的观点。此递归调用允许在UIViewController内的每个UIPageViewController之间进行动画。

// We call this method recursively until we find our desired view controller
// We do it this way to provide an animated transition if you find yourself in
// the first view and want to go to the last one. If we just jumped to the
// desired VC, we will not se any animation between the different VCs in the
// middle and it would look like there are only two VCs
func segmentedControl(index: Int) {
    let desiredVC = pages[index]
    if pages[currentIndex] != desiredVC {
        if index > currentIndex {
            self.setViewControllers([pages[currentIndex+1]], direction: .forward, animated: true, completion: nil)
            currentIndex += 1
        } else {
            self.setViewControllers([pages[currentIndex-1]], direction: .reverse, animated: true, completion: nil)
            currentIndex -= 1
        }
        segmentedControl(index: index)
    }
}

我的UISegmentedControl只是将选定的索引发送到此方法。

答案 1 :(得分:-1)

我不知道你的解决方案,但可能会对你有帮助。

Pageviewcontroller