Как разместить элемент UIPageControl поверх скользящих страниц внутри UIPageViewController?

StackOverflow https://stackoverflow.com//questions/21045630

Вопрос

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

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

Как можно поместить элемент управления поверх представлений, чтобы просмотр страниц был полноэкранным (например, с изображением), чтобы пользователь мог видеть представления под фиксированным элементом управления?

Я приложил пример скриншота - спасибо AppCoda и путь:

enter image description here

Это было полезно?

Решение 2

После дальнейшего расследования и поиска Я нашел решение, также в stackoverflow.

Ключом является следующее сообщение для отправки на пользовательский UIPageControl элемент:

[self.view bringSubviewToFront:self.pageControl];

Учебное пособие по AppCoda является основой этого решения.:

Добавить UIPageControl элемент поверх RootViewController - контроллер представления со стрелкой.

Создайте связанный IBOutlet элемент в твоем ViewController.m.

в 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];
}

Другие советы

У меня не было предложений прокомментировать ответ, который возникл это, но мне это действительно нравится.Я улучшил код и преобразовал его в 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()
    }
}
.

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

sn3ek Ваш ответ помог мне пройти большую часть пути.Я не установил текущую страницу с помощью viewControllerCreation методы однако.

я сделал свой ViewController also делегат UIPageViewController.Затем я установил PageControl's CurrentPage в этом методе.Используя 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];
}
.

Тогда нет необходимости поддерживать отдельный Uipageconrol и такое.

Вот 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

Существует 2 метода, которые необходимо реализовать, чтобы установить индикатор текущей страницы.

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

Вот Swifty 2 ответа очень на основе ответа @ Zerotool выше.Просто подкласс UipageViewController, а затем добавьте этот переопределение, чтобы найти ScrollView и изменить размер.Затем возьмите контроль страницы и переместите его на вершину всего остального.Вам также необходимо установить страницу элементы управления фоном цвета, чтобы очистить.Эти последние две линии могут пойти в ваш делегат приложения.

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()
.

BTW - я не замечаю никаких бесконечных петель, как упоминалось выше.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top