以编程方式在两个 UIViewController 之间切换
Posted
技术标签:
【中文标题】以编程方式在两个 UIViewController 之间切换【英文标题】:Switch between two UIViewControllers programmatically 【发布时间】:2012-08-15 13:17:51 【问题描述】:我有两个 xib 文件,每个文件都有一个覆盖 UIViewController 类的类。我在第一个 xib 文件中有一个按钮,当它被按下时应该带我到新的 UIViewController。我设法以不同的方式实现了这种转变:
UIViewController* secondViewController = [[UIViewController alloc] initWithNibName:@"SecondViewControllerName" bundle:[NSBundle mainBundle]];
[self.view addSubview:secondViewController.view];
或
UIViewController* secondViewController = [[UIViewController alloc] initWithNibName:@"SecondViewControllerName" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:secondViewController animated:YES];
在第二个 UIViewController xib 文件中,我还有一个按钮可以让我回到第一个 UIViewController。但我不知道如何导航回第一个 UIViewController。
我试过了:
[self.navigationController popViewControllerAnimated:YES];
对于导航到第二个 UIViewController 的第二种方式,但我得到 unrecognized selector sent to instance 错误。
非常感谢任何形式的帮助。
[编辑#1:添加源代码]
这是第一个视图控制器.m文件的源代码:
#import "ViewController.h"
#import "SecondViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
- (void)viewDidUnload
[super viewDidUnload];
// Release any retained subviews of the main view.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
- (IBAction)switchToSecondPage:(id)sender
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
[UIView beginAnimations:@"flipping view" context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition: UIViewAnimationTransitionCurlDown forView:self.view cache:YES];
[self.view addSubview:secondViewController.view];
[UIView commitAnimations];
@end
这里是第二个视图控制器.m文件的源代码:
#import "SecondViewController.h"
@interface SecondViewController ()
@end
@implementation SecondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
// Custom initialization
return self;
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
- (void)viewDidUnload
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
return (interfaceOrientation == UIInterfaceOrientationPortrait);
- (IBAction)switchToFirstPage:(id)sender
[UIView beginAnimations:@"flipping view" context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationTransition: UIViewAnimationTransitionCurlUp forView:self.view.superview cache:YES];
[self.view removeFromSuperview];
[UIView commitAnimations];
@end
这是我的 AppDelegate.m 文件:
#import "AppDelegate.h"
#import "ViewController.h"
@implementation AppDelegate
@synthesize window = _window;
@synthesize viewController = _viewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
- (void)applicationWillResignActive:(UIApplication *)application
- (void)applicationDidEnterBackground:(UIApplication *)application
- (void)applicationWillEnterForeground:(UIApplication *)application
- (void)applicationDidBecomeActive:(UIApplication *)application
- (void)applicationWillTerminate:(UIApplication *)application
@end
整个项目被制作为单视图应用程序,并针对 XCode 4.3 中的 ios 5.1。我找到了示例项目,它与我遇到的问题相同。这是该项目的 URL:http://www.devx.com/wireless/Article/42476/0/page/2 它只是为早期的 iOS 版本编写的。有没有人能看出我做错了什么,因为我真的没有想法?
PS:无论是否在代码中使用此动画,都会出现同样的问题,所以动画没有问题,我已经检查过了。
[编辑#2:添加错误信息]
这是错误描述。在返回行的 main 方法中如下所示:
int main(int argc, char *argv[])
@autoreleasepool
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
我收到此错误:
线程 1:EXC_BAD_ACCESS(代码=1,地址=0xc00000008)
[编辑#3:解决方案]
我要感谢@btype 下面的解决方案。我发现了为什么编辑#2 中的代码不起作用。问题是这样做:
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
IBAction 方法的内部!看起来 ARC 会在到达范围结束时立即擦除我的 UIViewController,这就是为什么我得到有关向已发布实例发送消息的信息的原因。我在 ViewController 类中创建了 SecondViewController 私有字段,之后一切正常。
如果有人认为我的解释是错误的并且知道真正困扰我的地方,请随时回答这个问题并纠正我。
【问题讨论】:
【参考方案1】:编辑代码:
在 AppDelegate.m 中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
ViewController *viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
FirstViewController.m
- (IBAction)switchToSecondPage:(id)sender
[self.navigationController pushViewController:secondViewController animated:YES];
SeconViewController.m
- (IBAction)switchToFirstPage:(id)sender
[self.navigationController popToRootViewControllerAnimated:YES];
这应该会有所帮助。
【讨论】:
我刚刚写给@jackiedigital。 IBAction 没有被调用,但是我的第二个 UIViewController 中的 viewDidLoad 也没有被调用。而且我很确定我已将 IBAction 正确附加到此 xib 文件中的唯一 UIButton。 检查您的文件所有者是否具有相同的类?视图插座是否连接到您的视图?您的按钮是否连接到文件所有者?您是否将按钮的“内部修饰”事件连接到文件所有者 IBAction 方法?只是想提供一些提示...... 我有 FirstViewController 和 SecondViewController(.m 和 .h)文件。 FirstViewController 设置为第一个 xib 文件的文件所有者,SecondViewController 设置为第二个 xib 文件。我有一个 IBOutlet 用于第一个 xib 文件上的按钮,还有一个 IBOutlet 用于第二个按钮。它们与 xib 文件上的按钮连接良好,但目前我没有使用该连接进行任何操作。我为第一个xib文件上的按钮制作了IBAction,它转换到第二个,并且正在调用该方法并转换到第二个UIViewController。我在 SecondViewController 类中所做的相同。 我已将该 IBAction 连接到“Touch Up Inside”事件中我唯一的按钮。我不知道我是否错过了检查任何内容,也不知道我做错了什么。 如果您的 IBAction 连接正确,则应该调用您的方法。你检查过你的 IBAction 的命名吗?头文件和主文件一样吗?尝试设置视觉提示(例如,为按钮制作红色背景以识别其是否正确视图)。以上是关于以编程方式在两个 UIViewController 之间切换的主要内容,如果未能解决你的问题,请参考以下文章
UINavigationController appDelegate UIViewController 以编程方式
UINavigationController appDelegate UIViewController以编程方式
如何为我在 Swift 中以编程方式创建的 UIViewController 子类创建 init?
在 UIViewController 中使用 UITableViewController 以编程方式自动布局
在 SWIFT 2.x 中以编程方式使用 NavigationController 调用 UIViewController