0

標準の「カバーバーティカル」セグエトランジションの逆を行おうとしているカスタムセグエがあります。私はこれがうまくいくと思います:

UIView *srcView = ((UIViewController *)self.sourceViewController).view;
UIView *dstView = ((UIViewController *)self.destinationViewController).view;

[dstView setFrame:CGRectMake(0, 0, srcView.window.bounds.size.width, srcView.window.bounds.size.height)];

[srcView.window insertSubview:dstView belowSubview:srcView];

[UIView animateWithDuration:0.3
     animations:^{
         srcView.center = CGPointMake(srcView.center.x - srcView.frame.size.width, srcView.center.y);
     }
     completion:^(BOOL finished){
         [srcView removeFromSuperview];
     }
 ];

問題は、アプリ内の他のすべてのビューが横向きであるにもかかわらず、宛先ビューが縦向きで表示されることです。また、x座標とy座標が逆になります。なぜこうなった?

私はすべてのViewControllerにセットアップしshouldAutorotateToInterfaceOrientationましたが、それは役に立ちませんでした。でビューを回転させることはできますがCGAffineTransformMakeRotation、それは正しいことではないようです。一つには、座標はまだ逆になります。

アップデート:

ビューを回転させるために使用してみCGAffineTransformRotateましたが、ばかげているように見えます。背景のほとんどが黒く表示されます。私はこれがそれが機能すると思われる方法ではないと思います。

4

5 に答える 5

3

コントローラを交換する前に、宛先ビューの正しい方向とフレーミングを取得できなかったため、プロセスを逆にしました。

  1. ソースビューを画像として保存します(カスタムアニメーションを使用したカスタムUIStoryboardSegueの削除を参照)。
  2. 現在のコントローラーを切り替えます[presentViewController:...];
  3. 次に、保存されたソース画像を埋め込んだ(現在は正しい)宛先ビューを使用してアニメーションを実行します。

完全なコードは次のとおりです。

#include <QuartzCore/QuartzCore.h>

@implementation HorizontalSwipingSegue

- (void) perform {
    UIViewController *source = self.sourceViewController;
    UIViewController *destination = self.destinationViewController;    
    UIView *sourceView = source.view;
    UIView *destinationView = destination.view;

    // Create a UIImageView with the contents of the source
    UIGraphicsBeginImageContext(sourceView.bounds.size);
    [sourceView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *sourceImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    UIImageView *sourceImageView = [[UIImageView alloc] initWithImage:sourceImage];

    [[self sourceViewController] presentViewController:[self destinationViewController] animated:NO completion:NULL];

    CGPoint destinationViewFinalCenter = CGPointMake(destinationView.center.x, destinationView.center.y);
    CGFloat deltaX = destinationView.frame.size.width;
    CGFloat deltaY = destinationView.frame.size.height;

    switch (((UIViewController *)self.sourceViewController).interfaceOrientation) {
       case UIDeviceOrientationPortrait:
            destinationView.center = CGPointMake(destinationView.center.x - deltaX, destinationView.center.y);                
            sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaX, sourceImageView.center.y);
            break;
        case UIDeviceOrientationPortraitUpsideDown:
            destinationView.center = CGPointMake(destinationView.center.x + deltaX, destinationView.center.y);
            sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaX, sourceImageView.center.y);
            break;
        case UIDeviceOrientationLandscapeLeft:
            destinationView.center = CGPointMake(destinationView.center.x, destinationView.center.y - deltaY);                
            sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaY, sourceImageView.center.y);
            break;
        case UIDeviceOrientationLandscapeRight:
            destinationView.center = CGPointMake(destinationView.center.x, destinationView.center.y + deltaY);
            sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaY, sourceImageView.center.y);
            break;
    }

    [destinationView addSubview:sourceImageView];

    [UIView animateWithDuration:0.6f
                     animations:^{
                         destinationView.center = destinationViewFinalCenter; 
                     }
                     completion:^(BOOL finished){
                         [sourceImageView removeFromSuperview];
                     }];
}

@end
于 2012-11-18T11:43:54.000 に答える
1

更新された回答:

dstViewのフレームを正しく設定していることを確認してください。私はあなたが使用してより幸運になると思います:

dstView.frame = srcView.frame;

それ以外の:

[dstView setFrame:CGRectMake(0, 0, srcView.window.bounds.size.width, srcView.window.bounds.size.height)];

プロパティは、bounds方向の変化に同じように反応しませんframe

于 2012-07-26T16:30:34.410 に答える
1

どうやら、私が望んでいたセグエをすることは私が思っていたよりもはるかに簡単でした。うまくいったのは次のとおりです。

- (void)perform {
    UIViewController *src = (UIViewController *)self.sourceViewController;
    [src dismissViewControllerAnimated:YES completion:^(void){ [src.view removeFromSuperview]; }];
}

うまくいけば、これは他の誰かを助けるでしょう。

于 2012-08-06T18:01:30.420 に答える
0

別のビューコントローラのビューをビュー階層に追加するだけの場合、そのビューコントローラはデバイスの向きに関する情報を取得しないため、デフォルト構成でビューが表示されます。ここで説明する包含メソッドを使用して、ViewControllerをViewController階層にも追加する必要があります。また、完了したら階層から削除する必要があります。

また、このテーマに関するいくつかの優れたWWDCの講演があります。1つは「ビューコントローラーの封じ込めの実装」と呼ばれる2011年のもので、もう1つは今年のビューコントローラーの進化です。

于 2012-07-26T16:46:16.473 に答える
0

交換

[srcView insertSubview:dstView belowSubview:srcView];

[srcView insertSubview:dstView atIndex:0];
于 2012-07-26T16:35:41.313 に答える