呈现视图控制器已经出现在现在呈现视图控制器下的意见将被删除了“模态”后;这节省了内存,并简化了渲染。但就你而言,你最终还是会看到“模态”展示视图背后的窗口。
自然的,看似合乎逻辑的下一步是简单地将一个视图控制器的视图填充到另一个视图中。但是,正如您发现的那样,这是有问题的。通过视图层次安全地保留新插入的视图是安全的,但新的视图控制器并不那么幸运,它很快就会被释放。所以当这个新视图试图联系它的控制器时,你会得到一个EXC_BAD_ACCESS
和崩溃。一种解决方法,就像您发现的那样,仅仅是让原始视图控制器保持对新视图控制器的强大引用。这可以工作......糟糕。您仍然有机会获得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];
您将通过后台看到的只是足够长的动画发生,那么我们用我们保存的图像隐藏去除呈现视图。
您不需要另一个视图控制器在xib中创建视图。你可以有一个只是视图的xib。现在,根据你对这个视图做什么,你可能希望它有自己的控制器,但这不是必需的。 – rdelmar
一个可以看到视图的xib。我认为这是即时通讯之后。有没有教程来说明如何使用它? – Jim
你需要什么教程?只需选择“新建文件”,选择“用户界面”作为类型,然后选择“查看”。 – rdelmar