2012-12-19 165 views
2

我想获得一个弹出式的效果,并希望在另一个视图控制器中设计弹出视图,所以我可以使用xib来做到这一点。添加另一个视图控制器的视图作为子视图

当我使用presentViewController或pushViewController并将背景设置为透明时,我最终看到窗口的背景色。

我试过这段代码,将subview添加到导航控制器的视图,以便我可以让Info视图用透明背景覆盖整个屏幕。我也有标签栏来掩盖。

InfoVC *vc = [[InfoVC alloc] initWithNibName:@"InfoVC" bundle:nil]; 
[self.navigationController.view addSubview:vc.view]; 

我的问题是我的InfoVC里面当我尝试将其关闭,应用程序将与一些EXC_BAD_ACCESS消息崩溃:

[self.view removeFromSuperview]; 

编辑:

我找到了一种方法来阻止它崩溃但将InfoVC设置为MainVC中的属性。我认为崩溃的原因是当我在InfoVC中的动作中调用“self.view”时,它不知道self是MainVC中的InfoVC。

+1

您不需要另一个视图控制器在xib中创建视图。你可以有一个只是视图的xib。现在,根据你对这个视图做什么,你可能希望它有自己的控制器,但这不是必需的。 – rdelmar

+0

一个可以看到视图的xib。我认为这是即时通讯之后。有没有教程来说明如何使用它? – Jim

+0

你需要什么教程?只需选择“新建文件”,选择“用户界面”作为类型,然后选择“查看”。 – rdelmar

回答

1

你不应该使用以下从其超级视图中删除视图吗?

[vc.view removeFromSuperview]; 
2
InfoVC *vc = [[InfoVC alloc] initWithNibName:@"InfoVC" bundle:nil]; 
[self.navigationController.view addSubview:vc.view]; 

没有没有没有没有。永远不要这样做。

为了将视图控制器的视图放入另一个视图控制器的视图(或将其移除),必须经过精心设计的舞蹈,如果它没有内置设施来执行此操作(方式为a UISplitViewController的确如此,或者是导航控制器管理视图控制器的视图的方式,这些视图被推入并弹出)。

阅读客户货柜控制器。一个从我的书中的例子是在这里:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/ch19p556containerController/p476containerController/ViewController.m

+0

谢谢,所以我在做什么不在正确的轨道上。 – Jim

+0

我会记住这一点。我还没有准备好创建自己的容器然后= D – Jim

+0

然后,只需使用一个视图,并离开额外的视图控制器。您可以随时弹出视图进出其他视图。只是不要在过程中滥用视图控制器。 – matt

1

呈现视图控制器已经出现在现在呈现视图控制器下的意见将被删除了“模态”后;这节省了内存,并简化了渲染。但就你而言,你最终还是会看到“模态”展示视图背后的窗口。

自然的,看似合乎逻辑的下一步是简单地将一个视图控制器的视图填充到另一个视图中。但是,正如您发现的那样,这是有问题的。通过视图层次安全地保留新插入的视图是安全的,但新的视图控制器并不那么幸运,它很快就会被释放。所以当这个新视图试图联系它的控制器时,你会得到一个EXC_BAD_ACCESS和崩溃。一种解决方法,就像您发现的那样,仅仅是让原始视图控制器保持对新视图控制器的强大引用。这可以工作......糟糕。您仍然有机会获得UIViewControllerHierarchyInconsistencyException

当然,如果你只是想增加你在IB创建一个小的视图,你不需要使用视图控制器作为“File's Owner”,并有从xib文件创建一个视图的一个实例的例子很多。

更有趣的问题是,“苹果怎么做?” Apple坚持认为视图控制器是封装工作单元的正确控制器。例如,他们的TWTweetComposeViewController,你介绍它,它似乎漂浮。 如何?

实现这一点的第一种方法出现在我的脑海里,就是有一个清晰的背景。也就是说,在呈现的视图控制器出现之前创建屏幕的图像,并在呈现视图被移除之前将其设置为背景。因此,例如,(下面再说明):

QuickSheetViewController.xib

enter image description here

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]; 

您将通过后台看到的只是足够长的动画发生,那么我们用我们保存的图像隐藏去除呈现视图。

相关问题