Cra*_*res 10 iphone xcode objective-c ios uistoryboardsegue
假设我们有三个视图控制器:1,2和3.使用故事板,使用展开segue从视图控制器3展开到视图控制器1非常简单.然而,当展开时,在显示视图控制器1之前,视图控制器2可以短暂可见.有没有办法从3到1而不再显示2?
查看控制器1:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"one did appear");
}
- (IBAction)goToTwo:(id)sender {
NSLog(@"#### segue to two");
[self performSegueWithIdentifier:@"TwoSegue" sender:self];
}
- (IBAction)unwindToOne:(UIStoryboardSegue *)sender {
}
Run Code Online (Sandbox Code Playgroud)
查看控制器2:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"two did appear");
}
- (IBAction)goToThree:(id)sender {
NSLog(@"#### segue to three");
[self performSegueWithIdentifier:@"ThreeSegue" sender:self];
}
Run Code Online (Sandbox Code Playgroud)
查看控制器3:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"three did appear");
}
- (IBAction)unwindToOne:(id)sender {
NSLog(@"#### unwind to one");
[self performSegueWithIdentifier:@"OneSegue" sender:self];
}
Run Code Online (Sandbox Code Playgroud)
这会产生以下日志消息:
我尝试过使用自定义segues和禁用动画.虽然删除动画会使视图控制器2出现的时间更短,但仍然会出现.有没有办法编程这种行为?
故事板的屏幕截图:
这似乎是由于展开搜索搜索最近的视图控制器的方式所致,该控制器实现了在情节提要中指定的展开动作。从文档中:
展开搜索如何选择其目的地
触发放开序列时,它必须找到最接近的视图控制器,该控制器执行定义放开序列时指定的放出动作。该视图控制器成为展开搜索的目的地。如果找不到合适的视图控制器,则取消中止搜索。搜索顺序如下:
一条
viewControllerForUnwindSegueAction:fromViewController:withSender:
消息发送到源视图控制器的父级。一条
viewControllerForUnwindSegueAction:fromViewController:withSender:
消息发送到下一个父视图控制器[...]如果对视图控制器是否应处理展开动作有特定要求,则可以重写canPerformUnwindSegueAction:fromViewController:withSender:
您的示例中的视图控制器没有父级,因此似乎后备(我看不到有关文档)是实例化每个实例presentingViewController
并canPerformUnwindSegueAction
依次调用它们。NO
从此方法返回ViewControllerTwo
不会阻止其实例化和显示,因此无法解决问题。
我已经尝试过将代码嵌入导航控制器中,并且效果很好。这是因为在这种情况下,它UINavigationController
是每个视图控制器的父级,并且它处理目标视图控制器的所有选择。更多文档:
容器视图控制器
容器视图控制器在展开过程中有两个职责,下面分别讨论。如果使用的是SDK提供的容器视图控制器,例如UINavigationController,则会自动处理这些控制器。
如果要创建一个简单的容器视图控制器来充当三个视图控制器的父代,则可以使用其viewControllerForUnwindSegueAction
方法在调用canPerformUnwindSegueAction
该控制器之前检查其每个子控制器是否存在展开动作,最后返回该控制器返回的第一个YES
。
选择一个子视图控制器来处理展开动作
如“展开选择如何选择其目的地”中所述,展开选择的源视图控制器将其父视图推迟到要处理该展开动作的视图控制器中。您的容器视图控制器应重写清单2中所示的方法,以在其子视图控制器中搜索要处理展开动作的视图控制器。如果容器的子视图控制器中的任何一个都不希望处理展开动作,则应调用上级的实现并返回结果。
容器视图控制器应以对该容器有意义的方式搜索其子级。例如,UINavigationController从导航堆栈顶部的视图开始,通过其viewControllers数组向后搜索。
清单2重写此方法,以返回要处理展开动作的视图控制器。-(UIViewController *)viewControllerForUnwindSegueAction:(SEL)来自ViewController的动作:(UIViewController *)来自具有发件人:[id] sender的ViewController
容器视图控制器设计有Apple专门撰写的整篇文章,在这里我不会重复(在这个答案中,Apple的写作已经足够多了!),但是看起来需要一些思想来解决它,因为它取决于您希望它们在应用程序中扮演的确切角色。
一种快速的解决方法,是使用放松的搜索来获得所需的行为,可以将视图控制器嵌入UINavigationController
,然后使用来隐藏导航栏。
[self.navigationController setNavigationBarHidden:YES];
Run Code Online (Sandbox Code Playgroud)
乔什的回答让我找到了解决方案。以下是实现此目的的方法:
创建根 UINavigationController,并将其分配给扩展 UINavigationController 并覆盖 segueForUnwindingToViewController:fromViewController:identifier 方法的类。如果需要,可以通过标识符进行过滤。
自定义导航控制器:
- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier {
return [[CustomUnwindSegue alloc] initWithIdentifier:identifier source:fromViewController destination:toViewController];
}
Run Code Online (Sandbox Code Playgroud)
创建一个自定义推送转场,其行为类似于模态转场,但使用我们的导航控制器。将其用于所有“推送”segue。
自定义PushSegue:
-(void) perform{
[[self.sourceViewController navigationController] pushViewController:self.destinationViewController animated:NO];
}
Run Code Online (Sandbox Code Playgroud)
创建一个自定义展开转场,它使用导航控制器弹出到目的地。这是由我们的导航控制器在 segueForUnwindingToViewController:fromViewController:identifier 方法中调用的。
自定义UnwindSegue:
- (void)perform {
[[self.destinationViewController navigationController] popToViewController:self.destinationViewController animated:NO];
}
Run Code Online (Sandbox Code Playgroud)
通过利用这些模式的组合,第二个视图控制器在展开过程中永远不会出现。
新的日志输出:
我希望这可以帮助其他人解决同样的问题。
归档时间: |
|
查看次数: |
4882 次 |
最近记录: |