11

私は s を学習しようとしてUIPageViewControllerいて、解決できない問題にぶつかりました。これは私がやろうとしたことです:

  • 手順:
    1. StoryBoard に 2 つのビュー コントローラーとページ ビュー コントローラーを作成しただけです。
    2. 次に、ファイルの所有者に、およびそれ自体PageViewControllerとして動作するコードを追加しました。dataSourcedelegate
    3. 私が走ったとき、物事はうまくいきました。
    4. いくつかのボタンとテキスト フィールドを 2 番目のビュー コントローラーに追加しました。
    5. 私は走った、よく働いた。
    6. 次に、テキスト ビューを 2 番目のビュー コントローラーに追加して実行しました。テキスト ビュー内に何かを書き込もうとすると、ページ コントロールがジッターし、最初のビュー コントローラーに移動しました。

誰もこれを経験したことがありますか?

@interface AMPageViewController : UIPageViewController <UIPageViewControllerDataSource, UIPageViewControllerDelegate>

@end

実装:

#import "AMPageViewController.h"

@interface AMPageViewController ()
{
    UIViewController *mainController;
    UIViewController* socController;
}
@end

@implementation AMPageViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard"
                                                             bundle: nil];

    mainController = (UIViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"First"];
    socController = (UIViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"Second"];
    [self setViewControllers:@[mainController]
                   direction:UIPageViewControllerNavigationDirectionForward
                    animated:NO
                  completion:nil];
    self.dataSource = self;
    self.delegate = self;
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    if (viewController == socController )
        return mainController;
    else return nil;
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    if (viewController == mainController )
        return socController;
    else return nil;
}

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
    return 2;
}

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
    return 0;
}


@end

プロジェクトをダウンロードして試してみたい場合

4

3 に答える 3

7

私はこの問題について多くのことを調査しました。UIPageViewController の内部 (プライベート) UIScrollView に関連するバグのようです。StackOverflow で検索すると、この問題と解決策のない多くの投稿が見つかります...

UITextView(これはUIScrollViewであり、AFAIRには内部UIWebViewがあります)がスーパービューチェーンに奇妙なメッセージを送信し、UIPageViewControllerのプライベートUIScrollViewが左上隅にスクロールするようです。

メソッドの入れ替えを使用してこのメ​​ッセージをブロックしようとしましたが、これはおそらく AppStore には適していません。だから私は他のことを試しました。

最終的な解決策は非常にシンプルです。UITextView を UIScrollView 内に埋め込むだけです。

これは更新されたプロジェクトへのリンクです

そうすれば、問題は解決します!

試してみて、私に知らせてください

編集:

どうやってこの解決策にたどり着いたのですか:

直感。

多くのデバッグ トレースとスタック トレースから、この問題は「入れ子になっている UIScrollView」システムのバグと、内部ビューからそのスーパービューに送信されたいくつかのメッセージに関連していると思われました。

UITextView は UIScrollView を継承し、別の UIScrollView である UIWebDocumentView (プライベート) を内部に持っています。デバッグ中に、上部の UIScrollView に送信された「relayout superview」のようなメッセージ (プライベート メソッド) がたくさん見られました。そのため、何らかの理由で、内部スクロール ビュー (UIWebDocumentView?) がメッセージ/イベントをスーパービューに送信していました。このメッセージ/イベント (おそらくバグのため) は外部の UITextView に停止せず、UIPageViewController によって処理される UIScrollView に転送されました。

単純な UIView 内に UITextView を埋め込むだけでは不十分でした。これは、UIView が処理できない場合にメッセージをそのスーパービューに転送するためです。私は思った:UIScrollViewはおそらくそうではありません(そうでなければ、UIScrollViewをネストするのは簡単ではありません)ので、試してみましたがうまくいきました。

調査を中止したため、これはすべて推測です。今週はさらに詳しく見ていきます。

于 2013-05-05T21:20:43.887 に答える
1

ビルド ターゲット iOS-7.0。

スクロールビューのトリックはうまくいきませんでした。ストーリーボードとコードを使用してテキストビューをスクロールビューに埋め込もうとしましたが、うまくいきませんでした。

テキストビューへの呼び出しを遅らせるだけでそれができました。あまりエレガントではありませんが、これまでに作業した唯一のものです。

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.textView becomeFirstResponder];
    });
}

iPhone 5 と超低速の iPhone4 でテスト済み。実装の詳細が何であれ、テキストビューがレスポンダーになることを可能にする可能性は十分にありますが、設定された時間よりも長くかかる可能性があります。したがって、これは完全に防弾ではないことに注意してください。

- 編集 -

ええと...それは私のiPhone 4ビーターで動作していますが、0.0000000000000001

于 2014-07-03T06:05:59.803 に答える
0

View Controllerの前後に設定せず、socControllerのファーストレスポンダーも調べていません

于 2013-05-01T08:02:50.887 に答える