Как поместить элемент UIPageControl поверх скользящих страниц в UIPageViewController?
в связи с этим учебник по AppCoda о том, как реализовать приложение с помощью UIPageViewController Я хотел бы использовать пользовательский элемент управления страницей в верхней части страниц, а не внизу.
когда я просто помещаю элемент управления страницей поверх отдельных представлений, которые будут отображаться, логическим результатом является то, что элементы управления прокручиваются с видом страницы от экрана.
Как можно поместить элемент управления поверх просмотры таким образом, просмотры страниц являются полноэкранными (например, с изображением), чтобы пользователь мог видеть представления под фиксированным элементом управления?
Я приложил пример скриншот-кредиты к AppCoda и путь:

7 ответов:
после дальнейшего расследования и поиска Я нашел решение, также на 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 ваш ответ получил меня большую часть пути туда. Я не устанавливал текущую страницу с помощью методы.
я
ViewController alsoпредставительUIPageViewController. Затем я установилPageControl' sCurrentPageв этом методе. Используя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]; }не забудьте добавить это
viewDidLoadself.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 { .1 } .map { .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()кстати-я не замечаю никаких бесконечных циклов, как упоминалось выше.
Comments