「モーダル」に表示されたビューコントローラが表示された後、現在表示されているビューコントローラの下のビューが削除されます。これによりメモリが節約され、レンダリングが容易になります。ただし、あなたの場合は、「モーダル」に表示されたビューの背後にウィンドウが表示されることにもなります。
自然で、一見論理的に見える次のステップは、あるビューコントローラのビューを取得し、それを別のビューコントローラに詰め込むことです。ただし、ご存知のとおり、これには問題があります。新しく挿入されたビューがビュー階層によって安全に保持されるため、安全ですが、新しいビューコントローラはそれほど幸運ではなく、すぐに割り当てが解除されます。したがって、この新しいビューがそのコントローラーに接続しようとすると、がEXC_BAD_ACCESS
発生してクラッシュします。繰り返しになりますが、回避策の1つは、元のViewControllerに新しいViewControllerへの強力な参照を保持させることです。そして、これはうまくいく可能性があります...ひどく。を取得する可能性はまだ十分にありますUIViewControllerHierarchyInconsistencyException
。
もちろん、IBで作成した小さなビューを追加したいだけの場合は、ビューコントローラを「File's Owner
」として使用する必要はありません。ファイルからビューのインスタンスを作成する例はたくさんありxib
ます。
ここでのより興味深い質問は、「アップルはそれをどのように/行うのか?」です。Appleは一貫して、ビューコントローラはカプセル化された作業単位の正しいコントローラであると言っています。たとえば、彼らTWTweetComposeViewController
、あなたはそれを提示し、それは浮かんでいるようです。どのように?
私の頭に浮かぶこれを達成するための最初の方法は、明確ではない明確な背景を持つことです。つまり、提示されたビューコントローラが表示される前に画面の画像を作成し、それを提示されたビューが削除される前の背景として設定します。だから例えば(続く説明):
QuickSheetViewController.xib
QuickSheetViewController.h
#import <UIKit/UIKit.h>
@interface QuickSheetViewController : UIViewController
- (IBAction)dismissButtonPressed:(id)sender;
@end
QuickSheetViewController.m
#import "QuickSheetViewController.h"
#import <QuartzCore/QuartzCore.h>
@implementation QuickSheetViewController {
UIImage *_backgroundImage;
}
-(void)renderAndSaveBackgroundImageFromVC:(UIViewController *)vc{
UIGraphicsBeginImageContext(vc.view.bounds.size);
[vc.view.layer renderInContext:UIGraphicsGetCurrentContext()];
_backgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
// save an image of the current view, and set our background to clear so we can see the slide-in.
[self renderAndSaveBackgroundImageFromVC:self.presentingViewController];
self.view.backgroundColor = [UIColor clearColor];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
// Time to use our saved background image.
self.view.backgroundColor = [UIColor colorWithPatternImage:_backgroundImage];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
// Set our background to clear so we can see the slide-out.
self.view.backgroundColor = [UIColor clearColor];
}
- (IBAction)dismissButtonPressed:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end
この例の大部分は、renderAndSaveBackgroundImageFromVC:
メソッドに依存しています。ここでは、グラフィックスコンテキストを作成して、これからカバーしようとしているビューをレンダリングしてから、UIImage
後で(でviewDidAppear
)背景として使用するためのを作成します。
今、単にそれを次のように使用します:
QuickSheetViewController *newVC = [[QuickSheetViewController alloc] initWithNibName:nil bundle:nil];
[self presentViewController:newVC animated:YES completion:nil];
アニメーションが発生するのに十分な時間だけ背景が透けて見えるので、保存した画像を使用して、表示されているビューの削除を非表示にします。