隐藏UIPageViewController中的圆点

57

我希望做一件非常简单的事情。只是删除UIPageViewController底部的所有点和线。

设置如下:我有一个自定义视图控制器,其中包含UIPageViewController *pageController。我像这样显示它:

self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

self.pageController.dataSource = self;
[[self.pageController view] setFrame:[self.view bounds]];

BSItemPageViewController *initialViewController = [self viewControllerAtIndex:selectedIndex];

NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];

[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];

[self addChildViewController:self.pageController];
[[self view] addSubview:[self.pageController view]];
[self.pageController didMoveToParentViewController:self];

有什么方法可以去掉这些点呢?


这是一个苹果的标志性功能,大多数用户都会看到。那么他们怎么知道需要切换页面呢?事实上,现在许多网站也在使用它。随着每个页面的自动更改,点也会更改。 - logixologist
我理解这一点,并且我正在按照苹果的指南完成我的应用程序,但这只是一种次要的导航方式,而且有很多项目,所以我宁愿不要有点。 - Stefan Salatic
5个回答

209

只有当数据源实现了这些方法时,页面控制才会显示:

presentationCountForPageViewController:
presentationIndexForPageViewController:

只需移除这些方法的实现,页面控件就不会显示。来自数据源文档

如果实现了 “Supporting a Page Indicator” 中的两种方法,并且页面视图控制器的转换样式为UIPageViewControllerTransitionStyleScroll,则会显示一个页面指示器。


5
如果您需要语音朗读页面编号(1/5、2/5等),那么这个解决方案就无法使用。否则,它是可行的。 - Lee
2
我添加了一个解决方案来解决@Lee提到的可访问性问题。基本上,只需调用UIPageControl.appearance().isHidden = true(Swift解决方案)。 - Daniel

13

在我的情况下,我有多个UIPageViewControllers(从-[UITableView didSelectRowAtIndexPath]创建),其中一些仅包含1页。 我没有为不同的UITableView行使用不同的控制器,而是按照以下方式实现了UIPageViewController委托方法:

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
    return ([self numberOfPages] == 1 ? 0 : [self numberOfPages]);
}

如果只有一页,则返回0,这似乎会导致UIPageViewController不显示点。这是一个丑陋的解决方法,但它似乎有效(iOS SDK 7.0)。

我想一种“更清晰”的方法是在运行时删除那些只有1页的UIPageController的方法,但这将涉及一些复杂的objC运行时操作。

对此方法有何评论?


1
如果你想提问,请不要将其放在回答中,而是为此开启一个新的线程。 “提问”按钮位于此页面的右上角。 这样更多的人会看到你的问题并尝试回答。 - sth
2
@sth,非常感谢您的评论,因为我不是Stack Overflow的经常贡献者。这里有什么首选协议吗?我已经回答了OP的问题,所以我认为那部分应该作为答案提交。但我认为我的问题在原始问题的背景之外没有多少意义。您是在建议我开始一个新线程以便征求对我的方法的评论吗?也许我不应该要求评论? - mts
3
您可以配置UIPageControl,以便在只有一页时自动隐藏小圆点。在Swift中:let pageControl = UIPageControl.appearance(); pageControl.hidesForSinglePage = true - user2067021

4

如果您希望在运行时动态隐藏这些点,则可以从presentationIndexForPageViewController代理中返回-1:

func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
    return yourPageVCs.count
}

func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
    return yourPageVCs.count > 1 ? 0 : -1
}

在这种情况下,如果你只有1页(单面),则会隐藏点。

当页面计数不会动态更改时,这个方法效果很好。 - Muhammed Basil
我该如何在运行时更改这个? - swalkner
@muhammedbasil,上面的代码在运行时是动态变化的。 - Ronak Vora

2

上述修复方法在一开始页面数量固定的情况下可以正常工作。

当页面数量可以动态增加或减少时,我尝试了不同的方法来解决这个问题。

因此,我使用了以下方法,手动隐藏组件本身。

func togglePageControl(pageCount: Int, threshold: Int = 1) {

    var hidden = true

    if pageCount > threshold {

        hidden = false

    }

    for subView in self.view.subviews {
        if subView is UIScrollView {
            subView.frame = self.view.bounds
        } else if subView is UIPageControl {
            subView.isHidden = hidden
        }
    }
}

并且应该从这里调用

public func presentationCount(for pageViewController: UIPageViewController) -> Int {

    togglePageControl(pageCount: pages.count)

    // or togglePageControl(pageCount: pages.count, threshold: 5)

    return pages.count
}

2

正如Lee指出的那样,仅仅不实现presentationCountForPageViewControllerpresentationIndexForPageViewController方法会在Voiceover期间出现无法读取页面编号(1/5、2/5等)的无障碍问题。一个支持无障碍性的解决方案是:

// Swift
let proxy = UIPageControl.appearance()
proxy.isHidden = true

// Objective-C
UIPageControl *proxy = [UIPageControl appearance];
[proxy setHidden:YES];

这样做有一个额外的好处,就是保持数据源和其呈现之间更清晰的分离。

更新: 不幸的是,这不是一个完美的解决方案,因为它隐藏了控件,但没有将其删除(仍然存在一个与隐藏控件高度相同的空白空间)。我还没有找到一种方法来配置现有的控件来解决这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接