UIPageViewController内のスライドページの上にUIPageControl要素を配置するにはどうすればよいですか?
-
21-12-2019 - |
質問
これに関しては UIPageViewControllerを使用してアプリを実装する方法についてのAppCodaによるチュートリアル カスタム ページ コントロール要素をページの下部ではなく上部で使用したいと考えています。
表示される単一のビューの上にページ コントロール要素を配置すると、論理的な結果として、コントロール要素はページ ビューとともにスクロールして画面から遠ざかります。
コントロール要素をビューの上に配置して、ページビューが(画像のように)全画面表示になり、ユーザーが固定コントロール要素の下にあるビューを表示できるようにするにはどうすればよいですか?
スクリーンショットの例を添付しました - クレジットは AppCoda とパス:
解決 2
StackOverflowでも、ソリューションを見つけました。
キーは、カスタムUIPageControl
要素に送信するための次のメッセージです。
[self.view bringSubviewToFront:self.pageControl];
.
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];
}
. 他のヒント
これを発信した答えについてコメントする担当者はありませんでしたが、私は本当に好きです。コードを改善し、UIPageViewControllerの以下のサブクラスのSWIFTに変換しました。
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
の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];
}
.
それから別の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
現在のページ インジケーターを設定するには 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
}
}
}
これは上記の@ Zerotoolの答えに基づいて非常にSwifty 2回答です。uipageViewControllerのサブクラスで、次にこの上書きを追加してScrollViewを見つけてサイズ変更します。次にページコントロールをつかみ、それを他のすべてのものの上に移動します。また、ページコントロールの背景色をクリアする必要があります。最後の2行はあなたのアプリの代わりに行くことができます。
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 - 上記のように、無限ループに気付いていません。