繁体   English   中英

如何将UIPageControl元素放在UIPageViewController中的滑动页面之上?

[英]How to put the UIPageControl element on top of the sliding pages within a UIPageViewController?

关于如何使用UIPageViewController实现应用程序的AppCoda教程,我想在页面顶部而不是底部使用自定义页面控制元素。

当我只是将页面控制元素放在将要显示的单个视图的顶部时,逻辑结果是控件元素滚动,页面视图远离屏幕。

如何将控制元素置于视图顶部以使页面视图全屏(如图像),以便用户可以看到固定控件元素下面的视图?

我附上了一个示例屏幕截图 - 来自AppCoda和Path的信用:

在此输入图像描述

我没有让代表对这个产生的答案发表评论,但我真的很喜欢它。 我改进了代码并将其转换为swift以用于UIPageViewController的以下子类:

class UIPageViewControllerWithOverlayIndicator: UIPageViewController {
    override func viewDidLayoutSubviews() {
        for subView in self.view.subviews as! [UIView] {
            if subView is UIScrollView {
                subView.frame = self.view.bounds
            } else if subView is UIPageControl {
                self.view.bringSubviewToFront(subView)
            }
        }
        super.viewDidLayoutSubviews()
    }
}

干净,效果很好。 无需维护任何内容,只需将您的页面视图控制器作为故事板中此类的实例,或者使您的自定义页面视图控制器类继承此类。

经过进一步的调查和搜索, 我找到了一个解决方案 ,也在stackoverflow上。

键是要发送到自定义UIPageControl元素的以下消息:

[self.view bringSubviewToFront:self.pageControl];

AppCoda教程是此解决方案的基础

RootViewController顶部添加一个UIPageControl元素 - 带箭头的视图控制器。

ViewController.m创建相关的IBOutlet元素。

viewDidLoad方法中,您应该添加以下代码作为添加所有子视图后调用的最后一个方法。

[self.view bringSubviewToFront:self.pageControl];

要根据当前内容视图的pageIndex分配当前页面,可以将以下内容添加到UIPageViewControllerDataSource方法中:

- (UIPageViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    // ...
    index--;
    [self.pageControl setCurrentPage:index];

    return [self viewControllerAtIndex:index];
}

- (UIPageViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    // ...
    index++;
    [self.pageControl setCurrentPage:index];

    // ...
    return [self viewControllerAtIndex:index];
}

sn3ek你的回答让我大部分都在那里。 我没有使用viewControllerCreation方法设置当前页面。

我使我的ViewController also成为UIPageViewController的委托。 然后我在该方法中设置PageControlCurrentPage 使用pageIndex维护我是原始文章中提到的ContentViewController

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
  APPChildViewController *currentViewController = pageViewController.viewControllers[0];
  [self.pageControl setCurrentPage:currentViewController.pageIndex];
}

不要忘记将其添加到viewDidLoad

self.pageViewController.delegate = self;

要跟进PropellerHead的注释, ViewController的界面将具有该表单

@interface ViewController : UIViewController <UIPageViewControllerDataSource, UIPageViewControllerDelegate>

只需通过子类化UIPageViewController并覆盖viewDidLayoutSubviews,即可实现相同的效果,如下所示:

-(void)viewDidLayoutSubviews {
    UIView* v = self.view;
    NSArray* subviews = v.subviews;
    if( [subviews count] == 2 ) {
        UIScrollView* sv = nil;
        UIPageControl* pc = nil;
        for( UIView* t in subviews ) {
            if( [t isKindOfClass:[UIScrollView class]] ) {
                sv = (UIScrollView*)t;
            } else if( [t isKindOfClass:[UIPageControl class]] ) {
                pc = (UIPageControl*)t;
            }
        }
        if( sv != nil && pc != nil ) {
            // expand scroll view to fit entire view
            sv.frame = v.bounds;
            // put page control in front
            [v bringSubviewToFront:pc];
        }
    }
    [super viewDidLayoutSubviews];
}

然后就没有必要保持单独的UIPageControl等。

这是我查看其他回复后放在一起的RxSwift / RxCocoa答案。

let pages = Variable<[UIViewController]>([])
let currentPageIndex = Variable<Int>(0)
let pendingPageIndex = Variable<(Int, Bool)>(0, false)

let db = DisposeBag()

override func viewDidLoad() {
    super.viewDidLoad()
    pendingPageIndex
        .asDriver()
        .filter { $0.1 }
        .map { $0.0 }
        .drive(currentPageIndex)
        .addDisposableTo(db)

    currentPageIndex.asDriver()
        .drive(pageControl.rx.currentPage)
        .addDisposableTo(db)
}

func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
    if let index = pages.value.index(of: pendingViewControllers.first!) {
        pendingPageIndex.value = (index, false)
    }
}

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    pendingPageIndex.value = (pendingPageIndex.value.0, completed)
}

您必须实现自定义UIPageControl并将其添加到视图中。 正如其他人所提到的,必须调用view.bringSubviewToFront(pageControl)

我有一个例子的图控制器的与上设置的自定义的所有代码UIPageControl与(在情节串连图板) UIPageViewController

您需要实现两种方法来设置当前页面指示器。

func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [UIViewController]) {
    pendingIndex = pages.indexOf(pendingViewControllers.first!)
}

func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    if completed {
        currentIndex = pendingIndex
        if let index = currentIndex {
            pageControl.currentPage = index
        }
    }
}

以下是基于@ zerotool上面的答案的Swifty 2答案。 只需将UIPageViewController子类化,然后添加此覆盖以查找scrollview并调整其大小。 然后抓住页面控件并将其移动到其他所有内容的顶部。 您还需要将页面控件背景颜色设置为清除。 最后两行可以放在你的app委托中。

override func viewDidLayoutSubviews() {

    super.viewDidLayoutSubviews()

    var sv:UIScrollView?
    var pc:UIPageControl?

    for v in self.view.subviews{

        if v.isKindOfClass(UIScrollView) {

            sv = v as? UIScrollView

        }else if v.isKindOfClass(UIPageControl) {

            pc = v as? UIPageControl
        }
    }

    if let newSv = sv {

        newSv.frame = self.view.bounds
    }

    if let newPc = pc {

        self.view.bringSubviewToFront(newPc)
    }
}

let pageControlAppearance = UIPageControl.appearance()
pageControlAppearance.backgroundColor = UIColor.clearColor()

顺便说一句 - 如上所述,我没有注意到任何无限循环。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM