1
  1. Xcodeで新しいページベースのアプリケーションプロジェクトを開始します
  2. プロジェクトを実行し、いくつかのページをめくる
  3. シミュレーターまたはデバイスを回転させます
  4. =>ページビューコントローラーが最初のページに戻ります(1月)

手順4を防ぐにはどうすればよいですか。

編集:これは、アプリがシミュレーター/デバイスで起動した後に初めて回転したときにのみ発生します。テストデバイスでは、最新のXcode4.5とiOS6.0SimulatorおよびiOS6を使用しています。ブログなどから他のサンプルコードをダウンロードしても同じことが起こります。iOS6のバグかもしれません。

EDIT2:UIPageViewControllerに渡される最初のページビューは、最初の回転まで割り当てが解除されないことがわかりました。これは本当に私にはバグのように見えます。

4

5 に答える 5

4

(2014年からの更新:新しいページビューアプリケーションテンプレートから再開した場合、これはiOS7で修正されたようです。)

私もこのバグを経験しました。メインビューが再表示された後はいつでも開始するようです。私のアプリにはいくつかのフルスクリーンモーダルがあり、それらがなくなると同じ動作が発生します。

これはXCode4.5.1とiOS6で発生します-XCode4.4を再ダウンロードし、アプリをiOS5.1に戻すことで、これを「修正」しました。明らかに、優れた長期的な解決策ではありません。私はこれをレーダーに提出し、すでにログに記録されているというメモを受け取りました。

FWIW iOS6がリリースされた直後に、iBooksにも同じバグがあることに気づきましたが、最近のアップデートで修正されたようです。

于 2012-10-24T17:39:08.100 に答える
1

これが私のアプリでこの問題を修正する方法です。それは一種のハッキーな解決策ではないかと思いますが、それは風変わりなバグです。

コンテキスト:私のアプリは日記(Remembaryと呼ばれます)であり、各ページは異なる日の日記エントリです。現在表示されている日記エントリオブジェクトや現在の日付など、さまざまなアプリレベルの値を追跡する「AppContext」というシングルトンクラスがあります。毎日のdataViewControllerは、それ自体の日記エントリも追跡します。

最も難しい部分は、アプリが間違ったページを表示していることを検出できるコンテキストを見つけることでした。これは[RootViewControllerviewDidLayoutSubviews]にあることがわかったので、そのメソッドに次を追加しました。

// get the currently displaying page
DataViewController *currentPage = self.pageViewController.viewControllers[0];
// check if we're showing the wrong page
if ([currentPage myEntry] != [AppContext getCurrentEntry]) {        
    // jump to the proper page (the delay is needed to ensure that the rotation has fully completed)
    [self performSelector:@selector(forceJumpToDate:) 
               withObject:[AppContext getCurrentEntryDate] 
               afterDelay:0.5];
}

これがforceJumpToDate関数です。この関数は、基本的に現在の日付に基づいて新しいページを取得し、アニメーション化せずにそのページにジャンプするようにpageViewControllerに指示します。

- (void) forceJumpToDate:(NSDate *)targetDate {
    DataViewController *targetPage = [self.modelController viewControllerForDate:targetDate 
                                                                      storyboard:self.storyboard];
    NSArray *viewControllers = [NSArray arrayWithObject:targetPage];
    [self.pageViewController setViewControllers:viewControllers 
                                      direction:UIPageViewControllerNavigationDirectionForward 
                                       animated:NO 
                                     completion:NULL];
}

新しいページが強制的に配置されると、ユーザーは画面に一時的な一時的な中断に気付く場合がありますが、これは、間違ったページが表示される場合にのみ発生するため、改善されています。

これは私のアプリをiOS6にアップグレードする能力を深刻に妨げていたので、私はついにそれを理解できてうれしいです。

于 2012-10-25T17:56:27.303 に答える
1

これが私の解決策です:


//  RootViewController.m

#import "RootViewController.h"

#import "ModelController.h"

#import "DataViewController.h"

@interface RootViewController ()
@property (readonly, strong, nonatomic) ModelController *modelController;

//added
@property (strong, nonatomic) DataViewController *currentViewController;
@end

@implementation RootViewController

@synthesize modelController = _modelController;

//added
@synthesize currentViewController = _currentViewController;

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    // Configure the page view controller and add it as a child view controller.
    self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
    self.pageViewController.delegate = self;

    DataViewController *startingViewController = [self.modelController viewControllerAtIndex:0 storyboard:self.storyboard];
    NSArray *viewControllers = @[startingViewController];
    [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];

    self.pageViewController.dataSource = self.modelController;

    [self addChildViewController:self.pageViewController];
    [self.view addSubview:self.pageViewController.view];

    // Set the page view controller's bounds using an inset rect so that self's view is visible around the edges of the pages.
    CGRect pageViewRect = self.view.bounds;
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        pageViewRect = CGRectInset(pageViewRect, 40.0, 40.0);
    }
    self.pageViewController.view.frame = pageViewRect;

    [self.pageViewController didMoveToParentViewController:self];

    // Add the page view controller's gesture recognizers to the book view controller's view so that the gestures are started more easily.
    self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;

    //added
    self.currentViewController = self.pageViewController.viewControllers[0];
}

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

- (ModelController *)modelController
{
     // Return the model controller object, creating it if necessary.
     // In more complex implementations, the model controller may be passed to the view controller.
    if (!_modelController) {
        _modelController = [[ModelController alloc] init];
    }
    return _modelController;
}

#pragma mark - UIPageViewController delegate methods

/*
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{

}
 */


//added
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

{
    self.currentViewController = self.pageViewController.viewControllers[0];

}

- (DataViewController *)currentViewController
{
    if (!_currentViewController) _currentViewController = [[DataViewController alloc] init];
    return _currentViewController;
}



- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
    if (UIInterfaceOrientationIsPortrait(orientation) || ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)) {
        // In portrait orientation or on iPhone: Set the spine position to "min" and the page view controller's view controllers array to contain just one view controller. Setting the spine position to 'UIPageViewControllerSpineLocationMid' in landscape orientation sets the doubleSided property to YES, so set it to NO here.



        //deleted: UIViewController *currentViewController = self.pageViewController.viewControllers[0];
        //changed to self.currentViewController
        NSArray *viewControllers = @[self.currentViewController];
        [self.pageViewController setViewControllers:viewControllers
                                          direction:UIPageViewControllerNavigationDirectionForward
                                          animated:YES
                                          completion:NULL];

        self.pageViewController.doubleSided = NO;
        return UIPageViewControllerSpineLocationMin;
    }

    // In landscape orientation: Set set the spine location to "mid" and the page view controller's view controllers array to contain two view controllers. If the current page is even, set it to contain the current and next view controllers; if it is odd, set the array to contain the previous and current view controllers.
   // deleted:  DataViewController *currentViewController = self.pageViewController.viewControllers[0];
   //deleted: NSArray *viewControllers = nil;
    //added
     NSArray *viewControllers = @[self.currentViewController];

   //changed currentViewController to self.currentViewController
    NSUInteger indexOfCurrentViewController = [self.modelController indexOfViewController:self.currentViewController];

    if (indexOfCurrentViewController == 0 || indexOfCurrentViewController % 2 == 0) {
        UIViewController *nextViewController = [self.modelController pageViewController:self.pageViewController viewControllerAfterViewController:self.currentViewController];
        viewControllers = @[self.currentViewController, nextViewController];
    } else {
        UIViewController *previousViewController = [self.modelController pageViewController:self.pageViewController viewControllerBeforeViewController:self.currentViewController];
        viewControllers = @[previousViewController, self.currentViewController];
    }
    [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];


    return UIPageViewControllerSpineLocationMid;
}

@end
于 2013-06-06T18:49:02.087 に答える
0

何を防ぎたいですか?回転を防ぎたいですか?それが必要な場合は、RootViewController.m実装ファイルのshouldAutorotateToInterfaceOrientationの戻り値を変更します。

これを行ったとき、アプリはデバイスを回転させた後でも同じページ(月)を維持することができました。シミュレーターを使って、iPhoneとiPadの両方で試してみました。iPadでは、横向きモードでは一度に2か月表示されましたが、縦向きに戻すと、表示された2か月のうち最初の月が保持されました。これは私が6月に増加したときでした。コード行を変更せずにデフォルトのプロジェクトを使用しました。

于 2012-09-25T22:28:52.297 に答える
0

今日、私は自分のアプリでバグを取り除くために以下を使用できることを知りました(しかし、理由はわかりません)。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
        ...
         self.pageViewController.view.hidden = YES;
    }

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
        self.pageViewController.view.hidden = NO;
    }
于 2013-03-12T16:45:38.477 に答える