UIPageViewControllerは、ステータスバーをタップするときにテーブルビューが上にスクロールするのを防ぎます。
質問
この質問を投稿する前に検索しましたが、何も見つけることができませんでした。
私は巨大な問題を抱えています。私のアプリの基礎としてスクロールタイプのUIPageViewControllerがあり、3つの表示コントローラがあります。
View Controllerの1つ(ListTableView)には、テーブルビューと検索表示コントローラがあります。
問題は、通常の表ビューのようにステータスバーをタップするときに、テーブルビューの上部までスクロールできません。UipageViewControllerがこれに干渉していると思いますが、私はそれを修正する方法についてはわかりませんが、私は自分のアプリを壊れていないようにする必要があることを知っています。
提供された助けに感謝します。
私はこの場合には無関係であってもコードを求めることを知っていますが、ここではUIPageViewControllerを作成するためのものです:
#import "MainViewController.h"
@interface MainViewController ()
@property (nonatomic, strong) UIPageViewController *pageViewController;
@property (nonatomic, strong) NSArray *contentViewControllers;
@end
@implementation MainViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageView"];
self.pageViewController.dataSource = self;
UIViewController *settings = [self.storyboard instantiateViewControllerWithIdentifier:@"Settings"];
UIViewController *listTableView = [self.storyboard instantiateViewControllerWithIdentifier:@"List"];
UIViewController *first = [self.storyboard instantiateViewControllerWithIdentifier:@"First"];
self.contentViewControllers = [NSArray arrayWithObjects:settings,listTableView,first,nil];
[self.pageViewController setViewControllers:@[first] direction:UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
self.view.backgroundColor = [UIColor colorWithRed:(248.0/255.0) green:(248.0/255.0) blue:(248.0/255.0) alpha:1.0];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerBeforeViewController:(UIViewController *)viewController {
NSUInteger index = [self.contentViewControllers indexOfObject:viewController];
if (index == 0) {
return nil;
}
return self.contentViewControllers[index - 1];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerAfterViewController:(UIViewController *)viewController {
NSUInteger index = [self.contentViewControllers indexOfObject:viewController];
if (index >= self.contentViewControllers.count - 1) {
return nil;
}
return self.contentViewControllers[index + 1];
}
. 解決
溶液
チャット後、私たちは面白いことを発見しました。ページビューコントローラは、ビュー階層内の他のビューコントローラのビューを保持するため、scrollsToTop
の動作もキャプチャして干渉します。これは、消えているビューコントローラのscrollsToTop
内の各スクロールビューのためにviewWillDisappear:
を無効にする必要があります(そしてviewWillAppear:
で再度有効にします)。
元の調査
QuickとEasyの仕様:ScrollViewはUIPageViewController
のビューの唯一のサブビューです。
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
.
デバッガの検査:
(lldb) po [self.pageViewController.view recursiveDescription]
<_UIPageViewControllerContentView: 0x8d7c390; frame = (0 0; 320 480); clipsToBounds = YES; opaque = NO; autoresize = W+H; layer = <CALayer: 0x8d7c4a0>>
| <_UIQueuingScrollView: 0xa912800; frame = (0 0; 320 480); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x8d7cc90>; layer = <CALayer: 0x8d7c7e0>; contentOffset: {320, 0}>
| | <UIView: 0x8d7da00; frame = (0 0; 320 480); layer = <CALayer: 0x8d7da60>>
| | <UIView: 0x8d7dab0; frame = (320 0; 320 480); layer = <CALayer: 0x8d7db10>>
| | <UIView: 0x8d7db40; frame = (640 0; 320 480); layer = <CALayer: 0x8d7dba0>>
.
それに到達するためにいくつかのメソッドを使うことができます。最も簡単なことはself.pageViewController.view.subviews
を繰り返し、UIScrollView
のサブクラスであるものを見つけることです。唯一のサブビューであるため、1回の反復後にループが終了します。
この解決策は最適ですか?いいえ。それはエラーが発生しやすいですか?理論的には確かに。変わる可能性がありますか?ビュー階層がかなり論理的なものであるため、そうしないでください。 Appleによる小さな監視のためにアプリケーション全体を変更することに対処しなければならないのではなく、少なくともクイック修正を与えます(スクロールビューへのアクセスを使用してユーザーに提供する)。
他のヒント
-scrollToTop
のiOS 7ドキュメント
iPhoneでは、スクロール間のジェスチャーはもっとある場合は効果がありません ScrollStotopがYesに設定されている画面上のスクロールビューを1スクロール表示します。
あなたと同様の方法でuipageViewControllerを使っています。私のページコントローラの1つは、UiveViewControllerです。だから私はtwo-scrollviews-onscreen-no-scrolltotop
ポリシーによってダイニングされます。
カディのアイデア見えないボタンであなた自身のスクロールトトップの行動を実装するという考えは、おそらくこの状況で最も信頼できる賭けです。
UITableView
の子ビューコントローラにUIPageViewController
を持っていました。Leo Natanの提案から引っ張って、これを私の子ビューコントローラに追加するジョブは:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.tableView.scrollsToTop = YES;
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
self.tableView.scrollsToTop = NO;
}
.
述べたように、子ビューコントローラの競合するUIScrollView
は、互いのスクロールストロップデリゲート方法を妨害します。このコードは、一度にScrollStotopが一度に有効になっていることを確認します。
私はこれを使いました:
for v in view.subviews {
if v.isKindOfClass(UIScrollView) {
(v as! UIScrollView).scrollsToTop = false
}
}
.
しかし、上にスクロールできるScrollViewがまだある場合、あなたは機能しません。このスクリプトを使用して、他のScollsViewsを見つけます。 https://stackoverflow.com/a/a33443757/2589276 。その後、スクロールを上に無効にします。
その後、上にスクロールするViewControllerで、これらを追加します。
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
tableView.scrollsToTop = true
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
tableView.scrollsToTop = false
}
. 最良の解決策は、UIPageViewControllerDelegateプロトコルの2つの方法を使用していると思います(クイックとダーティバージョンでは、画面上に1つのビューコントローラーしか考慮しない):
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers
{
((UITableViewController *)pendingViewControllers[0].tableView).scrollsToTop = YES;
}
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
((UITableViewController *)previousViewControllers[0].tableView).scrollsToTop = NO;
}
.
編集:承認済み回答の
の最後の段落に概説されているアプローチ