2

トランジションにカスタムコントローラーを使用しています(プロジェクトに固有のサイクルがあるため、ナビゲーションコントローラーを使用できませんでした。これにより、ナビゲーションコントローラースタックが無限に大きくなる可能性があります[メモリの問題が発生すると想定しています])。UIView animateWithDuration:animations:completion: を使用して、ナビゲーション コントローラーのスライド アニメーション (新しい画面に遷移するとき) をエミュレートしています。

遷移をトリガーするボタンが押されると、遷移先の新しいビューのフレームが画面外の位置に設定されます。遷移のアニメーション (UIView animateWithDuration:animations:completion:) では、現在画面上にあるビューのフレームが画面外の位置に設定され、新しいビューが画面上の位置に設定されます。

これは、トランジション用のカスタム コントローラー内にあります。

CGFloat windowWidth = self.mainView.frame.size.width;
CGFloat windowHeight = self.mainView.frame.size.height;
CGRect offScreenLeft = CGRectMake(-1*windowWidth, 0.0, windowWidth, windowHeight);
CGRect onScreen = self.mainView.frame;
CGRect offScreenRight =  CGRectMake(windowWidth, 0.0, windowWidth, windowHeight);


if (direction == TransitionDirectionForward)
{
    if (dragBackgroundOnscreen){
        [self.mainView addSubview:self.backgroundView];
        [self.mainView sendSubviewToBack:self.backgroundView];
        self.backgroundView.frame = offScreenRight;
    } 


    self.currentViewController.view.frame = offScreenRight;

    [UIView animateWithDuration:0.65
                     animations:^{
                         oldViewController.view.frame = offScreenLeft;
                         if (dragBackgroundOffscreen)
                             self.backgroundView.frame = offScreenLeft;
                         else if (dragBackgroundOnscreen)
                             self.backgroundView.frame = onScreen;

                         self.currentViewController.view.frame = onScreen;
                     }
                     completion:^(BOOL finished){
                         [oldViewController.view removeFromSuperview];  
                         if (dragBackgroundOffscreen)
                             [self.backgroundView removeFromSuperview];
                         [oldViewController willMoveToParentViewController:nil];
                         [oldViewController removeFromParentViewController];
                         [self.currentViewController didMoveToParentViewController:self]; 
                     }];


}
else if (direction == TransitionDirectionBackward)
{
    if (dragBackgroundOnscreen){
        [self.mainView addSubview:self.backgroundView];
        [self.mainView sendSubviewToBack:self.backgroundView];
        self.backgroundView.frame = offScreenLeft;
    } 
    self.currentViewController.view.frame = offScreenLeft;
    [UIView animateWithDuration:0.65 
                     animations:^{
                         oldViewController.view.frame = offScreenRight;

                         if (dragBackgroundOffscreen)
                             self.backgroundView.frame = offScreenRight;
                         else if (dragBackgroundOnscreen)
                             self.backgroundView.frame = onScreen;

                         self.currentViewController.view.frame = onScreen;
                     }
                     completion:^(BOOL finished){
                         [oldViewController.view removeFromSuperview]; 
                         if (dragBackgroundOffscreen)
                             [self.backgroundView removeFromSuperview];
                         [oldViewController willMoveToParentViewController:nil];
                         [oldViewController removeFromParentViewController];
                         [self.currentViewController didMoveToParentViewController:self];
                     }];

} 

また、独自の背景を持つ画面に移動しない限り、背景 (self.backgroundView) を静的のままにしたい (つまり、新しいビューの背景が同じ背景である場合に背景をスライドさせたくない)。

左へのスライドと右へのスライドを区別するためだけに、TransitionDirectionBackward と TransitionDirectionForward を使用しています。

トランジションに GMGridView が含まれる場合を除いて、すべてがうまく機能します。Gridviews フレームがオフスクリーン フレームに設定されている場合の問題は、現在選択されているページのフレームをそのオフスクリーン フレームに実際に設定することです。グリッドビューの他のページはこのフレームに制限されていないため、遷移前でも画面に表示できます。GridView のビューコントローラーのビューでフレームと境界のプロパティを設定しようとしましたが、遷移アニメーションの前に画面に表示されるグリッドビューのページを取得できます。

誰でもこれに対する解決策を見ますか? トランジション中に GridView のビューをクリップして、現在選択されているページ以外のページが表示されないようにする方法を見つけようとしていましたが、有用なものは見つかりませんでした。

更新:表示されているが表示されるべきではないセルにアルファ= 0.0を設定することで、可能な修正を見つけました(後で遷移アニメーションが完了したときにアルファ= 1.0を設定します)。ただし、これを行うセルを知る必要があります。隣接するページのセルのアルファ値を 0.0 に設定できるように、GMGridView が現在表示されているページにアクセスする方法が必要です。

更新: myGridView convertPoint:(ページの最初のセルにあることが試行錯誤で見つかった cgpoint) を使用して、それを機能させる方法を見つけました。注:デバイスが回転してもウィンドウ座標が回転しないため、横向きの左または横向きの右にあるかどうかを確認するには、if/else ifが必要でした。これにより、指定した画面上のポイントでセルのインデックスを取得し、遷移アニメーションの後まで前のページを透明に設定することができました。

グリッドビューを「クリッピング」して、セルを不透明にする方法があるかどうかを知りたいのですが、表示されない場合は....?

4

1 に答える 1

2

私は問題を複雑にしすぎたと思います。私は UIView のメソッドを探していました clipsToBounds (以前にそれを試したと誓ったかもしれませんが)。いずれにせよ、それは今働いています!

于 2012-08-10T19:32:41.487 に答える