web-dev-qa-db-ja.com

UIPageViewControllerがスクロールしているときに通知する(画像の視差スクロールの場合)

新しいYahoo天気アプリで見られるような効果を作成しようとしています。基本的に、UIPageViewControllerの各ページには背景画像があり、ページビューをスクロールすると、画像の場所は約半分の速度でしかスクロールしません。どうすればいいですか? UIPageViewControllerにある種のデリゲートメソッドを使用して現在のオフセットを取得し、そのような画像を更新できると思いました。唯一の問題は、UIPageViewControllerがスクロールされているかどうかを判断できないことです!その方法はありますか?ありがとう!

29
Keiran Paster
for (UIView *view in self.pageViewController.view.subviews) {
    if ([view isKindOfClass:[UIScrollView class]]) {
         [(UIScrollView *)view setDelegate:self];
    }
} 

これにより、すべての標準スクロールビューAPIメソッドにアクセスできます。そして、これはプライベートApple APIを使用していません。

サブビューを走査して、UIPageViewControllerの内部スクロールビューを100%見つけるために追加しました[〜#〜] warning [〜#〜]:注意してくださいscrollview.contentOffset。コントローラが新しいページにスクロールするとリセットされます

パーシジョンscrollviewオフセットトラッキングなどが必要な場合は、コレクションビュー自体のサイズのセルでページングを有効にしたUICollectionViewControllerを使用することをお勧めします。

48
Pavel Gurov

私はこれをします:

Objective-C

for (UIView *v in self.pageViewController.view.subviews) {
    if ([v isKindOfClass:[UIScrollView class]]) {
        ((UIScrollView *)v).delegate = self;
    }
}

このプロトコルを実装します

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

スウィフト

for view in self.pageViewController.view.subviews {
  if let scrollView = view as? UIScrollView {
    scrollView.delegate = self
  }
}

このプロトコルを実装します

func scrollViewDidScroll(scrollView: UIScrollView)
15
Van Du Tran

@Paulのスニペットを使用-

_for (UIView *v in self.pageViewController.view.subviews) {
if ([v isKindOfClass:[UIScrollView class]]) {
    ((UIScrollView *)v).delegate = self;
}
}
_

このプロトコルを実装するには:-(void)scrollViewDidScroll:(UIScrollView *)scrollView

_-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGPoint point = scrollView.contentOffset;

float percentComplete;
percentComplete = fabs(point.x - self.view.frame.size.width)/self.view.frame.size.width;
NSLog(@"percentComplete: %f", percentComplete);
}
_

これにより、スクロールの完了率がわかります。ハッピーコーディング!

3
genaks

私の推測では、それはnot UIPageViewControllerではなく、ページ化されたUIScrollViewであると思われます。 UIScrollView doesは、スクロールが行われるときに何が起こっているかを追跡するデリゲートメソッドを常に繰り返し提供します。

あるいは、might UIPageViewControllerが密かに使用しているページ化されたUIScrollViewにアクセスできますが、何かを壊す可能性があり、Appleそれについて。

3
matt
extension UIPageViewController {

    var scrollView: UIScrollView? {

        return view.subviews.filter { $0 is UIScrollView }.first as? UIScrollView
    }
}

を使用して:

pageController.scrollView?.delegate = self
2
Mike Glukhov

Swift 3では、さらに短く書くことができます。

if let scrollView = self.pageViewController.view.subviews.first(where: { $0 is UIScrollView }) as? UIScrollView {
    scrollView.delegate = self
}
1
d.felber

探しているのは視差スクロールと呼ばれ、それを支援するいくつかのライブラリを見つけることができます。

編集:マットは正しい、これは答えではなく、単なるヒントです。とにかくそれを完了しましょう:

UIPageViewControllerの背後にある背景画像をアニメーション化するには、それが提供するデリゲートメソッドを使用する必要があります。

-[id<UIPageViewControllerDelegate> pageViewController:willTransitionToViewControllers:]
-[id<UIPageViewControllerDelegate> pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:]

これらの2つの方法を使用すると、スクロールの割合を計算できます(どのコントローラーでスクロールしたかを把握して割合を取得するには、コントローラーをアレイに格納する必要があります)

0
Antonio E.