两个UIViewControllers可以使用单个导航栏吗?

时间:2013-01-05 00:22:37

标签: iphone objective-c uinavigationbar

在我的iPhone应用程序中,我试图提供一个静态导航栏,因此切换视图时标题和按钮不会滑过。

我无法想到这样做(至少是这样),所以你有什么建议吗?我需要在导航栏空间中有一个静态标题和按钮(即使我不使用UINavigationBar,但要自定义),以便当我执行诸如推动视图控制器之类的操作时,当它在我的导航中滑动时栏不会移动,按钮会更改新视图的功能。

修改

好的,我想到了一种可能的方法。我的每个视图都有一个辅助视图,其中视图内容为gold,导航栏对象除外。我是否可以覆盖pop和push方法,只是在屏幕上和屏幕外设置此子视图的动画?

3 个答案:

答案 0 :(得分:3)

按正常方式进行推动,但将其设置为不动画。

[self.navigationController pushViewController:newViewController animated:NO];

然后当你想回去......

[self.navigationController popViewControllerAnimated:NO];

然后你可以有两个导航栏,但它看起来就像它没有动画一样是吧。

编辑并在视图中动画并保持NAV BAR

我不确定应用程序的整个流程,但是如果你想保留导航栏并刷新新的UI,那么你可以创建一个滚动视图(带分页)并将每个VC的视图放在不同的滚动视图的帧或其他东西。

为什么还要让导航栏保持不动?动画导航栏并在其上保留相同的按钮等没有任何问题。

话虽如此,如果您使用不同的VC,那么导航栏应该会改变,以显示您当前正在查看的VC的详细信息(即标题)。

另一种激进的方法

好的,现在横向思考:D

怎么样,你使用非动画的推送和弹出(如上所述),而不是只显示UI,你可以从相关的一侧动画它。 (然后,您为UI子类化的单例或VC子类可以在所有视图控制器中为您执行此操作)。

接下来的问题是,在新UI中设置动画之前,UI看起来会立即变为空白,因此您需要为旧UI设置动画。这意味着两个UI(旧的和新的)必须同时在屏幕上。

您可以通过将旧UI的整个视图转换为图像(不难发现将找到链接)然后将此图像传递到新VC来解决此问题。然后,新VC将立即显示此图像,并在将自己的UI设置到屏幕上的同时将其设置为屏幕外的动画。

真的不像听起来那么难。特别是如果您继承UIViewController广告,则为其提供一个函数animateUI和一个属性oldUIImagedirection。然后,您可以覆盖此类中的viewWillAppear以为您执行动画。然后你唯一需要做的就是当你按下/弹出它时给每个VC一个图像和一个方向。

这只是给出了你所追求的幻想,意味着你仍然可以保持一个相当简单的对象模型和应用流程。

......或其他什么。

答案 1 :(得分:2)

@ Fogmeister的好主意......

在呈现视图控制器中,按implementing the suggestion here获取self.view的图像。然后,当它出现的时候......

UIImage *image = [self makeImage];  // what it was called in the other post, consider a better name
MyViewController *newVC = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
newVC.presentationImage = image;
[self.navigationController pushViewController:newVC animated:NO];

在MyViewController中,给它一个名为presentationImage的UIImage属性,然后......

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:self.presentationImage];
    imageView.frame = self.view.bounds;
    imageView.tag = 128;
    [self.view addSubview:imageView];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIImageView *imageView = (UIImageView *)[self.view viewWithTag:128];
    [UIView animateWithDuration:0.5 animations:^{
        imageView.frame = CGRectOffset(imageView.frame, -self.frame.size.width, 0); 
    }];
}

仅供参考 - 我没有测试甚至编译它。刚喜欢这个想法,决定伸出手指。

答案 2 :(得分:0)

要以“干净”的方式执行此操作,您需要放弃UINavigationController并编写一个自定义容器控制器,在推送新视图控制器时不会将新导航项目推送到其导航栏上(或允许您推送动画推送视图控制器视图时,以非动画方式导航项目。)

但是这样做需要一些时间。如果您决定这样做,我建议在UIViewController包含上进行WWDC会话。

我想到的另一个选择是(通过子类化或方法调配)改变UINavigationController的行为,以在动画viewcontroller-push时动画导航项非动画。

我没有测试过这个,但是在这样的子类中覆盖push(和pop)可能有效:

- (void)pushViewController:(UIViewController *)vc animated:(BOOL)animated {
    [super pushViewController:vc animated:animated];
    [self.navigationBar setItems:self.navigationBar.items animated:NO];
}

如果此方法不起作用,可能需要在调用pushViewController之后直接检查导航栏内的动画:动画:。也许你可以取消一些动画直接进入最终状态。