2011-10-07 10 views
9

私のiPadアプリでは、小さなテーブルビューのビューコントローラがあります。テーブルビューをタップすると、小さいテーブルビューのより大きく洗練されたバージョンであるモーダルビューコントローラが開きます。大規模なビューコントローラの事前レンダリングされたイメージから、小さなテーブルビューのサイズになるようにイメージを縮小し、フルスクリーンサイズにズームしてイメージを「実際の」ビューに置き換えることによってアニメーションを作成したいコントローラ。ズームを使用してUIViewControllerを表示するにはどうすればよいですか?

ような何か:私はあなたがビューから画像を生成することができます知っている

LargeViewController* lvc = [[LargeViewController alloc] init]; 
[self presentModalViewController:lvc byZoomingFromRect:CGRectMake(50,50,200,300)]; 

- (UIImage *) imageWithView:(UIView *)view 
{ 
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [[UIScreen mainScreen] scale]); 
    [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return img; 
} 

しかし、どのように私は、ビューコントローラドロー自体(オフスクリーン)作るんので、私はだそれを取ることができますスクリーンを埋めるためにアニメーションの画像を表示し、拡大縮小しますか?

ありがとうございます。

答えて

3

独自のアニメーションを作成するとします。先月、私はそのようなもので遊んだ。私の解決策は、現在のビューをオーバーレイとしてカスタムビュー(ビューコントローラから取った可能性があります)を追加することでした。これはレイヤーでも機能します。

まず、上記のコード例のように、「今後の」または「現在の」ビューコントローラーからイメージを取得します。通常、コンテキストにレンダリングしている間は、View Controllerのコンテンツを使用できるようにする必要があります。

これで画像があります。画像の操作は、あなたが行う必要があります。

イメージをUIImageViewに追加します。このImageViewは、サブビューまたはレイヤーとして追加できます。これで、実際のユーザーインターフェイスの上に自由に描画できるレイヤーができました。場合によっては、レイヤーまたはビューを移動してビューを完全にオーバーレイする必要があります。これはビューの設定によって異なります。あなたがTableviewsを扱っているなら、サブビューを追加するのは簡単ではありません。だから層をよく使う。

すべての作業が完了したら、すぐに表示されるように、アニメーションなしで新しいView Controllerを表示します。

作業が完了したら、親ビューからレイヤーまたはビューを削除し、クリーンアップします。

これは複雑ですが、これを済ませたらテンプレートがあります。 「WWDC 2011、Session 309 Interface Builder Storyboardingの紹介」では、リンゴは「カスタムセグ」を導入しました。ここでは、あなたがしたいことを正確に行う仕組みが見つかります。以下のコードは、古いプロジェクトを切り捨てたもので、なんとかしこまり、クリーンアップする必要があります。しかし、原則を示すためには、これはうまくいくはずです:

-(void) animate { 

     static LargeViewController* lvc = [[LargeViewController alloc] init]; 

     UIGraphicsBeginImageContextWithOptions(self.bounds.size, view.opaque, [[UIScreen mainScreen] scale]); 
    [lvc.view.layer renderInContext:UIGraphicsGetCurrentContext()]; 

     // Create a ImageView to display your "zoomed" image 
     static UIImageView* displayView = [[UIImageView alloc] initWithFrame:self.view.frame]; 
     static UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 

     // Add your image to the view 
     displayView.image = img; 

     // insert the view above your actual view, adjust coordinates in the 
     // frame property of displayView if overlay is misaligned 
     [[self.view] addSubview:displayView]; 

     // alternatively you can use the layer 
     // [self.view.layer addSublayer:displayView.layer]; 

     // draw the imageView 
     [displayView setNeedsDisplay]; 

     // do something in background. You may create your own 
     // construction, i.e. using a timer 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

      NSDate *now = [NSDate date]; 
      NSTimeInterval animationDuration = 3.; 
      NSTimeInterval t = -[now timeIntervalSinceNow]; 
      while (t < animationDuration) { 

       t = -[now timeIntervalSinceNow]; 

       // Do some animation here, by manipulation the image 
       // or the displayView 

       // <calculate animation>, do something with img 
       // you have exact timing information in t, 
       // so you can set the scalefactor derived from t 
       // You must not use an UIImage view. You can create your own view 
       // and do sth. in draw rect. Do whatever you want, 
       // the results will appear 
       // in the view if you added a subview 
       // or in a layer if you are using the layer 

       dispatch_sync(dispatch_get_main_queue(), ^{ 

        // display the result 
        displayView.image = img; 
        [displayView setNeedsDisplay]; 
       }); 
      } 
     }); 

     // now the animation is done, present the real view controller 
     [self presentModalViewController:lvc animated:NO]; 

     // and clean up here 
} 
+0

最後に、あなたの非常に詳細な提案をテストする時間がありました。魅力的な作品!入力いただきありがとうございます!そしてまた、WWDC 2011のセッション309は、カスタムの仕切りを使ってもうまくいきました。 –

0

おそらく、あなたはその後、存在LVCモーダル、あなたの親ビューコントローラのビューの縮小版を埋め込み、ユーザーがビューをタップしたときのスケールを復元するために

CGAffineTransform tr = CGAffineTransformScale(lvc.view.transform, 0.5, 0.5); 

のようなものを使用することができます。

0

UIKitがこれのほとんどを処理します。 jbat100のソリューションも動作させることができますが、最初にlvcの初期フレームを小さい方のrectに設定してから、フレームをフルサイズに設定すると、暗黙のアニメーションフレームを変更するとズームインアニメーションが処理されます。各UIViewには、そのコンテンツが描画されるCALayerがあり、そのレイヤーにはフレームや位置のプロパティなどの特定のプロパティのアニメーション化された変更を設定するいくつかの暗黙のアニメーションが設定されています。ここではそれで私のテストされていない刺しは次のとおりです。

 . 
     . 
    lvc.view.frame = CGRectMake(50,50,200,300); 
    [self performSelector:@selector(setFrameToFullScreen) withObject:nil afterDelay:0]; 

} 

- (void)setFrameToFullScreen { 
    lcv.view.frame = [UIScreen mainScreen].bounds; 
} 

performSelector:withObject:afterDelay呼び出しがsetFrameToFullScreenは、次の実行ループサイクルで呼び出されることになります。このようなことをしないと、最後のフレームだけが使用され、システムはフレームの変更を認識せず、暗黙的なアニメーションをviewsレイヤーに適用します。

+0

問題はビュークラスではないので、ビューコントローラにフレームプロパティがないことです。 View Controllerを表示するには、presentModalViewController:animated:メソッドを使用し、アニメーション自体を設定する方法があります。 –

+0

あなたの権利!ビューコントローラにはフレームがありませんが、そのビューにはフレームがあります。私はそれを反映するために上記のコードを編集しました。 – Logachu

関連する問題