从ModalViewController

时间:2016-01-25 13:38:46

标签: ios objective-c uiviewcontroller uiviewanimation uiviewanimationtransition

我有一个带3个视图控制器的应用程序。 A是根,B是下一个,C是单击B上的按钮时出现/转换的模态视图。我想要做的有时是当点击C上的按钮时直接从C移动到A(其他时候,应该发生C-> B转换,这是可以的)。我尝试了各种各样的选项,并收集了来自不同SO帖子的信息,但最后,卡在了从C到A的直接转换发生但偶尔显示B的情况。

有没有办法可以完全消除这种瞬间的B外观。此外,当用户从B转到C或从C转到B时,我确实需要动画。如果存在限制,那么C到A的转换不需要动画。

希望您可以填写...已复制相关代码及以下详细信息。

ViewControllerC.h:

@protocol ViewControllerCDelegate <NSObject>

- (void)didNavigateBackFromViewC:(ViewControllerC *)viewControllerC;

@end

@interface ViewControllerC : UIViewController

@property (nonatomic, weak) id < ViewControllerCDelegate > viewCDelegate;

@end

ViewControllerC.m:

- (IBAction)navigateToViewA:(id)sender
{
    [self.viewCDelegate didNavigateBackFromViewC:self];
}

对于B-> C和C-> B转换,我使用了一个单独的转换控制器,它是ViewControllerB的委托。另外,ViewControllerB是UIViewControllerTransitioningDelegate的委托......为了简单起见,我没有包含这些细节,但希望能够在这里传达有关C-&gt; A转换的问题。

ViewControllerB.h:

@interface ViewControllerB () <ViewControllerCDelegate>

@end

ViewControllerB.m:

- (void)didNavigateBackFromViewC:(ViewControllerC *)viewControllerC
{
    __block ViewControllerB *me = self;
    [viewControllerC dismissViewControllerAnimated:YES completion:^{
    [me.navigationController popToRootViewControllerAnimated:YES];
    }];
}

4 个答案:

答案 0 :(得分:0)

非常有趣的问题@ vikram17000。首先,您可能想尝试展开segues,看起来他们可以做你想要的但我还没有测试过。它显示你正在走程序路线,这就是我发现的。我将(后面的)和“主页”动作分成(我称之为)两个单独的动作。这是我的ViewControllerC代码:

>> x = [1 2 4 2 -1 3];
>> y = filter([0 1], 1, x)

y =

     0     1     2     4     2    -1

>> z = filter([0 1], 1, y)

z =

     0     0     1     2     4     2

ViewControllerB是获取-... WillGoHome的委托,并且在 VC C解散之前弹出了TopTootRC 。这得到了我们想要的行为,C动画出来,A就离开了 - 耶!不幸的是有一个问题 -

  

对ViewControllerB的开始/结束外观转换的不平衡调用:0x7fc3c857ca80。

有可能吗?是。操作系统喜欢它吗?不,不是的。希望这可以帮助你顺利进行。

答案 1 :(得分:0)

我为您的问题创建了示例project。 协议 GoBackProtocol 包含方法

-(void)controller:(UIViewController *)controller didPressBackButton:(UIButton *)button;

A和B控制器采用GoBackProtocol。 B控制器实现-controller:didPressBackButton:方法并根据按钮参数决定做什么:用动画隐藏呈现的控制器或隐藏它而不用动画并将调用转发给他的代表,即控制器A.

- (void)controller:(UIViewController *)controller didPressBackButton:(UIButton *)button
{
    ViewControllerC *modalController = (ViewControllerC *)controller;
    if (button == modalController.buttonB)
    {
        [controller.presentingViewController dismissViewControllerAnimated:YES completion:nil];
    }
    else if (button == modalController.buttonA)
    {
        [controller.presentingViewController dismissViewControllerAnimated:NO completion:nil];
        [self.delegate controller:self didPressBackButton:nil];
    }
}

Controller A实现-controller:didPressBackButton:同样弹出viewController B.

- (void)controller:(UIViewController *)controller didPressBackButton:(UIButton *)button
{
    [self.navigationController popViewControllerAnimated:YES];
}

All Together它可以产生预期的效果。

答案 2 :(得分:0)

请忘记此处的所有自定义协议解决方案。 Apple说: The presenting view controller is responsible for dismissing the view controller it presented.

IMO你至少有两个选择:

1)您可以将C上的关闭按钮添加到公共界面,如

@property (nonatomic, strong, readonly) UIButton *closeButton;

以不同方式设置目标并使用 dismissViewControllerAnimated:completion: popToRootViewControllerAnimated:的组合,如方法 didNavigateBackFromViewC

2)您可以在C中使用 self.navigationController.presentingViewController 来访问非模态视图控制器。

作为非官方选项,您可以直接在UINavigationController实例上设置viewcontrollers数组。然后你会得到一个从C到A的推动画。

答案 3 :(得分:0)

我尚未对此进行全面测试,但迄今为止的结果似乎令人鼓舞。鉴于我希望能够从A转换到B或C,并且B和C可以在彼此之间导航,我已经开始使用ViewControllerA作为ViewControllerB和ViewControllerC的容器视图控制器。这使我可以从A轻松访问B / C,以及使用自定义转换无缝转换B和C的能力。