在 iOS 中从 Presented View Controller 推送视图
Push View from Presented View Controller in iOS
简而言之:
如何从 Presented ViewController 推送 ViewController ?
简述:
我有 MainViewController
,其中我有一个单击按钮的按钮,我正在呈现一个名为 LoginViewController
的视图。
在此页面 (LoginViewController
) 上,我再次看到 button
,单击它时,我尝试推送我的视图控制器(称为 HomeViewController
),但它没有推送.
这是我的代码片段,
MainViewController.m
- (IBAction)LoginClicked:(id)sender {
LoginViewController *vc = [[LoginViewController alloc] init];
[self presentViewController:vc animated:YES completion:nil];
}
LoginViewController.m
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
NSLog(@"viewControllers %@",APPDELEGATE.nav.viewControllers);
//LoginViewController is not in this array
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
但这对我不起作用。另外,我在pushed
之前打印了a stack of view controllers
,但它没有LoginViewController
。因此,如果不将 LoginViewController
添加到 a stack of view controllers
,我如何从 LoginViewController
pushed
到 HomeViewController
?
当我从 HomeViewController
返回时,LoginViewController
应该会打开..
是否可以使用单次 NavigationController
?
注意:-这里,我只是以使用Login、Home 和Main ViewController 为例。但我想把它放到其他屏幕上。
创建 UINavigationController 实例
[[UINavigationController alloc] initWithRootViewController:[[LoginViewController alloc] init]]
显示那个 navigationController 然后按你想要的任何东西VC。
1) 呈现一个 navigation controller with its
根视图控制器` 设置为视图控制器。
- (IBAction)LoginClicked:(id)sender
{
LoginViewController *loginViewController = [LoginViewController alloc] init];
UINavigationController *navController = [UINavigationController alloc] initWithRootViewController:loginViewController];
[self presentViewController:navController animated:YES completion:nil];
}
- (IBAction)buttonActionMethodOnLoginView:(id)sender
{
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
希望对你有用。
嗨,当你展示你的登录视图控制器时,只需展示一个导航控制器,如:
LoginVC *loginVCObj =[[LoginVC alloc]initWithNibName:@"LoginVC" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:loginVCObj];
[self presentViewController:nav animated:YES completion:nil];
现在你的 PresentedViewController 是一个 navigtioncontroller
现在你可以简单地推送到你的主页 VC
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
希望对您有所帮助
MainViewController.m
- (IBAction)LoginClicked:(id)sender {
LoginViewController *vc = [[LoginViewController alloc] init];
UINavigationController *loginNav = [[UINavigationController alloc] initWithRootViewController:vc];
[self presentViewController:loginNav animated:YES completion:nil];
}
LoginViewController.m
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
NSLog(@"viewControllers %@",APPDELEGATE.nav.viewControllers);
//LoginViewController is not in this array
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
您必须从您的 firstView (MainViewController
) Push
,但您可以使用与 PresentView
和 DismissView
相同的动画。为此使用以下代码:-
用于推送(在MainViewController
)
LoginViewController *VC = [[LoginViewController alloc]init];
CATransition* transition = [CATransition animation];
transition.duration = 0.3f;
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer addAnimation:transition
forKey:kCATransition];
[[[UINavigationController alloc] initWithRootViewController:VC] pushViewController:VC animated:NO];
//[self.navigationController pushViewController:VC animated:NO];
流行(LoginViewController
)
CATransition* transition = [CATransition animation];
transition.duration = 0.3f;
transition.type = kCATransitionReveal;
transition.subtype = kCATransitionFromBottom;
[self.navigationController.view.layer addAnimation:transition
forKey:kCATransition];
[self.navigationController popViewControllerAnimated:NO];
使用此代码,您可以获得与Present-Dismiss ViewControllers
相同的动画。有关更多详细信息,请参阅 this answer。
之后,您可以将代码用于 Pushing
LoginViewController
到 HomeViewController
希望,这就是您要找的。有任何疑虑,请回复我。 :)
您不能从呈现的视图控制器中推送。我建议,你应该维护你的导航层次结构。
为此,从您的 MainViewController 中,您应该呈现 LoginViewController 并且您应该为 MainViewController 传递导航控制器。
- (IBAction)openLogin:(id)sender {
LoginViewController *loginVC = (LoginViewController *) [self.storyboard instantiateViewControllerWithIdentifier:@"login"];
[loginVC setReferencedNavigation:self.navigationController];
[self presentViewController:loginVC animated:YES completion:nil];
}
然后在 LoginViewController 中,你应该像这样推送到 HomeViewController,
LoginViewController.h
@interface LoginViewController : UIViewController {
UINavigationController *refNavigationController;
}
- (void) setReferencedNavigation:(UINavigationController *)refNavCon;
LoginViewController.m
- (void) setReferencedNavigation:(UINavigationController *)refNavCon {
refNavigationController = refNavCon;
}
- (IBAction)openHome:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
UIViewController *homeVC = [self.storyboard instantiateViewControllerWithIdentifier:@"home"];
[refNavigationController pushViewController:homeVC animated:YES];
}];
}
通过这样做,看起来您是从 LoginViewController 推送,但实际上您是从 MainViewController 推送。
您可以自定义此方法来维护此流程的动画和 UI。
问题是 LoginViewController
没有导航控制器。那你给它一个。
MainViewController.m
创建一个UINavigationController
,将LoginViewController
放入堆栈并呈现UINavigationController
。
- (IBAction)LoginClicked:(id)sender {
LoginViewController *vc = [[LoginViewController alloc] init];
UINavigationController = nav = [[UINavigationController alloc] init];
nav.viewControllers = @[vc];
[self presentViewController:nav animated:YES completion:nil];
}
LoginViewController.m
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
关闭
在您的 MainViewController
中调用 dismissViewControllerAnimated
。
LoginViewController
不应被推送到导航控制器堆栈。下面我来描述一下"why".
我们的 MainViewController
应该在堆栈上 - 你总是想回到那里。
// AppDelegate.m (only if you don't use storyboards, if you do - you don't need to copy this part of code)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// create the window
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setBackgroundColor:[UIColor whiteColor]];
[self.window makeKeyAndVisible];
// set view controllers
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[MainViewController alloc] init]];
[self.window setRootViewController:navigationController];
}
关于具体动作展示LoginViewController
。您不希望用户能够点击 back
并转到 MainViewController
。稍后,您不会希望用户返回 LoginViewController
。因此,您需要将其呈现为模态:
// inside `MainViewController.m`
- (IBAction)myCoolActionToShowLogin:(id)sender {
[self presentViewController:[[LoginViewController alloc] init] animated:YES completion:nil];
}
现在我们可以看到 LoginViewController
。当用户完成登录时,将其关闭并显示 HomeViewController
:
// inside `LoginViewController.m`
- (IBAction)myAwesomeActionToShowHome:(id)sender {
UINavigationController *navigationController = (UINavigationController *)[UIApplication.sharedApplication.keyWindow rootViewController];
[navigationController pushViewController:[[HomeViewController alloc] init] animated:YES];
[self dismissViewControllerAnimated:YES completion:nil];
}
备注:
您可能会注意到,myAwesomeActionToShowHome:
希望您有导航控制器作为您的 rootViewController
。这是可行的,但应该更好——您应该检查该导航是否实际上是导航控制器,而不是强制转换它。或者您可以创建一个委托或块来推送新委托。这是最快,最简单的解决方案,以后应该改进。
你真的应该阅读:Apple Developer -> "View Controller Programming" documentation,因为这些是你应该了解的核心基础知识来开发和设计用户体验正确。
这是工作 demo sample。
这是当前视图控制器和推送视图控制器的非常简单的代码。
- (IBAction)LoginClicked:(id)sender {
LoginViewController *objLogicVC = [LoginViewController alloc] init];
UINavigationController *navPresent = [UINavigationController alloc] initWithRootViewController:objLogicVC];
[self presentViewController:navPresent animated:YES completion:nil];
}
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
HomeViewController *objHomeVC = [[HomeViewController alloc] init];
[self.navigationController pushViewController:objHomeVC animated:YES];
}
只需将此代码放在 objective c 上 按钮 action
UIViewController *yourViewControllerName = [self.storyboard instantiateViewControllerWithIdentifier:@"yourViewControllerName "];
[[self navigationController] pushViewController:yourViewControllerName animated:YES];
为Swift3.0
将您的视图控制器呈现为新的 rootViewController
let navController = UINavigationController.init(rootViewController: self.storyboard!.instantiateViewController(withIdentifier: "SignInViewController"))
self.present(navController, animated: true, completion: {})
现在从呈现的视图控制器推送您的视图控制器
self.show(self.storyboard!.instantiateViewController(withIdentifier: "SignUpViewController"), sender: self)
简而言之: 如何从 Presented ViewController 推送 ViewController ?
简述:
我有 MainViewController
,其中我有一个单击按钮的按钮,我正在呈现一个名为 LoginViewController
的视图。
在此页面 (LoginViewController
) 上,我再次看到 button
,单击它时,我尝试推送我的视图控制器(称为 HomeViewController
),但它没有推送.
这是我的代码片段,
MainViewController.m
- (IBAction)LoginClicked:(id)sender {
LoginViewController *vc = [[LoginViewController alloc] init];
[self presentViewController:vc animated:YES completion:nil];
}
LoginViewController.m
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
NSLog(@"viewControllers %@",APPDELEGATE.nav.viewControllers);
//LoginViewController is not in this array
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
但这对我不起作用。另外,我在pushed
之前打印了a stack of view controllers
,但它没有LoginViewController
。因此,如果不将 LoginViewController
添加到 a stack of view controllers
,我如何从 LoginViewController
pushed
到 HomeViewController
?
当我从 HomeViewController
返回时,LoginViewController
应该会打开..
是否可以使用单次 NavigationController
?
注意:-这里,我只是以使用Login、Home 和Main ViewController 为例。但我想把它放到其他屏幕上。
创建 UINavigationController 实例
[[UINavigationController alloc] initWithRootViewController:[[LoginViewController alloc] init]]
显示那个 navigationController 然后按你想要的任何东西VC。
1) 呈现一个 navigation controller with its
根视图控制器` 设置为视图控制器。
- (IBAction)LoginClicked:(id)sender
{
LoginViewController *loginViewController = [LoginViewController alloc] init];
UINavigationController *navController = [UINavigationController alloc] initWithRootViewController:loginViewController];
[self presentViewController:navController animated:YES completion:nil];
}
- (IBAction)buttonActionMethodOnLoginView:(id)sender
{
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
希望对你有用。
嗨,当你展示你的登录视图控制器时,只需展示一个导航控制器,如:
LoginVC *loginVCObj =[[LoginVC alloc]initWithNibName:@"LoginVC" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:loginVCObj];
[self presentViewController:nav animated:YES completion:nil];
现在你的 PresentedViewController 是一个 navigtioncontroller 现在你可以简单地推送到你的主页 VC
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
希望对您有所帮助
MainViewController.m
- (IBAction)LoginClicked:(id)sender {
LoginViewController *vc = [[LoginViewController alloc] init];
UINavigationController *loginNav = [[UINavigationController alloc] initWithRootViewController:vc];
[self presentViewController:loginNav animated:YES completion:nil];
}
LoginViewController.m
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
NSLog(@"viewControllers %@",APPDELEGATE.nav.viewControllers);
//LoginViewController is not in this array
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
您必须从您的 firstView (MainViewController
) Push
,但您可以使用与 PresentView
和 DismissView
相同的动画。为此使用以下代码:-
用于推送(在MainViewController
)
LoginViewController *VC = [[LoginViewController alloc]init];
CATransition* transition = [CATransition animation];
transition.duration = 0.3f;
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer addAnimation:transition
forKey:kCATransition];
[[[UINavigationController alloc] initWithRootViewController:VC] pushViewController:VC animated:NO];
//[self.navigationController pushViewController:VC animated:NO];
流行(LoginViewController
)
CATransition* transition = [CATransition animation];
transition.duration = 0.3f;
transition.type = kCATransitionReveal;
transition.subtype = kCATransitionFromBottom;
[self.navigationController.view.layer addAnimation:transition
forKey:kCATransition];
[self.navigationController popViewControllerAnimated:NO];
使用此代码,您可以获得与Present-Dismiss ViewControllers
相同的动画。有关更多详细信息,请参阅 this answer。
之后,您可以将代码用于 Pushing
LoginViewController
到 HomeViewController
希望,这就是您要找的。有任何疑虑,请回复我。 :)
您不能从呈现的视图控制器中推送。我建议,你应该维护你的导航层次结构。
为此,从您的 MainViewController 中,您应该呈现 LoginViewController 并且您应该为 MainViewController 传递导航控制器。
- (IBAction)openLogin:(id)sender {
LoginViewController *loginVC = (LoginViewController *) [self.storyboard instantiateViewControllerWithIdentifier:@"login"];
[loginVC setReferencedNavigation:self.navigationController];
[self presentViewController:loginVC animated:YES completion:nil];
}
然后在 LoginViewController 中,你应该像这样推送到 HomeViewController,
LoginViewController.h
@interface LoginViewController : UIViewController {
UINavigationController *refNavigationController;
}
- (void) setReferencedNavigation:(UINavigationController *)refNavCon;
LoginViewController.m
- (void) setReferencedNavigation:(UINavigationController *)refNavCon {
refNavigationController = refNavCon;
}
- (IBAction)openHome:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
UIViewController *homeVC = [self.storyboard instantiateViewControllerWithIdentifier:@"home"];
[refNavigationController pushViewController:homeVC animated:YES];
}];
}
通过这样做,看起来您是从 LoginViewController 推送,但实际上您是从 MainViewController 推送。
您可以自定义此方法来维护此流程的动画和 UI。
问题是 LoginViewController
没有导航控制器。那你给它一个。
MainViewController.m
创建一个UINavigationController
,将LoginViewController
放入堆栈并呈现UINavigationController
。
- (IBAction)LoginClicked:(id)sender {
LoginViewController *vc = [[LoginViewController alloc] init];
UINavigationController = nav = [[UINavigationController alloc] init];
nav.viewControllers = @[vc];
[self presentViewController:nav animated:YES completion:nil];
}
LoginViewController.m
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
HomeViewController *obj = [[HomeViewController alloc] init];
[self.navigationController pushViewController:obj animated:YES];
}
关闭
在您的 MainViewController
中调用 dismissViewControllerAnimated
。
LoginViewController
不应被推送到导航控制器堆栈。下面我来描述一下"why".
我们的 MainViewController
应该在堆栈上 - 你总是想回到那里。
// AppDelegate.m (only if you don't use storyboards, if you do - you don't need to copy this part of code)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// create the window
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setBackgroundColor:[UIColor whiteColor]];
[self.window makeKeyAndVisible];
// set view controllers
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[MainViewController alloc] init]];
[self.window setRootViewController:navigationController];
}
关于具体动作展示LoginViewController
。您不希望用户能够点击 back
并转到 MainViewController
。稍后,您不会希望用户返回 LoginViewController
。因此,您需要将其呈现为模态:
// inside `MainViewController.m`
- (IBAction)myCoolActionToShowLogin:(id)sender {
[self presentViewController:[[LoginViewController alloc] init] animated:YES completion:nil];
}
现在我们可以看到 LoginViewController
。当用户完成登录时,将其关闭并显示 HomeViewController
:
// inside `LoginViewController.m`
- (IBAction)myAwesomeActionToShowHome:(id)sender {
UINavigationController *navigationController = (UINavigationController *)[UIApplication.sharedApplication.keyWindow rootViewController];
[navigationController pushViewController:[[HomeViewController alloc] init] animated:YES];
[self dismissViewControllerAnimated:YES completion:nil];
}
备注:
您可能会注意到,myAwesomeActionToShowHome:
希望您有导航控制器作为您的 rootViewController
。这是可行的,但应该更好——您应该检查该导航是否实际上是导航控制器,而不是强制转换它。或者您可以创建一个委托或块来推送新委托。这是最快,最简单的解决方案,以后应该改进。
你真的应该阅读:Apple Developer -> "View Controller Programming" documentation,因为这些是你应该了解的核心基础知识来开发和设计用户体验正确。
这是工作 demo sample。
这是当前视图控制器和推送视图控制器的非常简单的代码。
- (IBAction)LoginClicked:(id)sender {
LoginViewController *objLogicVC = [LoginViewController alloc] init];
UINavigationController *navPresent = [UINavigationController alloc] initWithRootViewController:objLogicVC];
[self presentViewController:navPresent animated:YES completion:nil];
}
- (IBAction)buttonActionMethodOnLoginView:(id)sender{
HomeViewController *objHomeVC = [[HomeViewController alloc] init];
[self.navigationController pushViewController:objHomeVC animated:YES];
}
只需将此代码放在 objective c 上 按钮 action
UIViewController *yourViewControllerName = [self.storyboard instantiateViewControllerWithIdentifier:@"yourViewControllerName "];
[[self navigationController] pushViewController:yourViewControllerName animated:YES];
为Swift3.0
将您的视图控制器呈现为新的 rootViewController
let navController = UINavigationController.init(rootViewController: self.storyboard!.instantiateViewController(withIdentifier: "SignInViewController"))
self.present(navController, animated: true, completion: {})
现在从呈现的视图控制器推送您的视图控制器
self.show(self.storyboard!.instantiateViewController(withIdentifier: "SignUpViewController"), sender: self)