Switch between two UIViewControllers programmatically - ios

I have two xib files and for each it's own class which overrides UIViewController class. I have a button in first xib file which should take me to new UIViewController when it's pressed. I have managed to make that transition in different ways:
UIViewController* secondViewController = [[UIViewController alloc] initWithNibName:#"SecondViewControllerName" bundle:[NSBundle mainBundle]];
[self.view addSubview:secondViewController.view];
or
UIViewController* secondViewController = [[UIViewController alloc] initWithNibName:#"SecondViewControllerName" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:secondViewController animated:YES];
In second UIViewController xib file I have also one button which should take me back to first UIViewController. But I don't know how to navigate back to first UIViewController.
I tried:
[self.navigationController popViewControllerAnimated:YES];
for second way of navigating to second UIViewController, but I get unrecognized selector sent to instance error.
Many thanks in advance for any kind of help.
[edit #1: Adding source code]
Here's source code of first view controller .m file:
#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
Here's source code of second view controller .m file:
#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
Here's my AppDelegate.m file:
#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
Entire project is made as Single View Application and targeted for iOS 5.1 in XCode 4.3. I have found sample project which does the same thing I am having trouble with. Here's URL for that project: http://www.devx.com/wireless/Article/42476/0/page/2
It is just written for earlier iOS version. Is anyone able to see what am I doing wrong, since I am really out of ideas?
PS: With this animations in code, or without - same problem occurs, so animations aren't problem, I've checked that.
[edit #2: Adding error info]
Here's error description. In main method on return line as listed below:
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
I get this error:
Thread 1: EXC_BAD_ACCESS (code=1, address=0xc00000008)
[edit #3: SOLUTION]
I would like to thank #btype for his solution below. I found out why code from edit #2 didn't work. Problem was doing this:
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
INSIDE OF IBAction METHOD! Looks like ARC wiped my UIViewController as soon as end of scope was reached and that's why I was getting informations about sending messages to released instance. I made SecondViewController private field in my ViewController class and after that everything worked just fine.
If anyone thinks my explanation is wrong and knows what really bothered me, feel free to answer to this question and correct me.

Edit the code:
in 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];
}
This should help.

Related

UINavigationController title in iOS seems corrupted

When I present a UINavigationController modally and then push (without animation) some UIViewcontrollers onto it, the finally shown navigationItem.title is different from what I would expect.
I tried to narrow my issue down and came up with the following short code to duplicate the issue:
#implementation DummyRootVC
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:[[Dummy1VC alloc] init]];
[self presentViewController:nc
animated:false
completion:nil];
}
#end
#implementation Dummy1VC
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor=[UIColor whiteColor];
self.navigationItem.title= #"DUMMY1";
[self.navigationController pushViewController:[[Dummy2VC alloc] init]
animated:false];
}
#end
#implementation Dummy2VC
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title= #"DUMMY2";
self.view.backgroundColor=[UIColor yellowColor];
[self.navigationController pushViewController:[[Dummy3VC alloc] init]
animated:false];
}
#end
#implementation Dummy3VC
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor=[UIColor orangeColor];
self.navigationItem.title= #"DUMMY3";
[self.navigationController pushViewController:[[Dummy4VC alloc] init]
animated:false];
}
#end
#implementation Dummy4VC
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title= #"DUMMY4";
self.view.backgroundColor=[UIColor greenColor];
for (UIViewController* vc in self.navigationController.viewControllers) {
NSLog(#"VC Stack: %# Title:%#",vc,vc.navigationItem.title);
}
NSLog(#"End");
}
#end
In AppDelegate I set:
self.window.rootViewController = [[DummyRootVC alloc] init];
When running that code the displayed title is „Dummy 2“ and the back-button is named „Dummy 4“, while I actually would expect a title „Dummy 4“ and a back-button named „Dummy 3“.
The log shows as expected the correct ViewController-Stack and the backgroundColor is (as expected) green (and interestingly is still green after one "back" click):
VC Stack: Title:DUMMY1
VC Stack: Title:DUMMY2
VC Stack: Title:DUMMY3
VC Stack: Title:DUMMY4
End
I could work around that issue since it seems somewhat related to the non-animation setting in combination with presenting the navigation controller modally, but I would like to understand the underlying issue…
Can anyone provide me with some insight? Is this some bug or am I doing (as I suspect) just something the wrong way?
Thanks!
Put the push/present from viewDidLoad to viewWillAppear or viewDidAppear so that the viewController can init it's subview correctly to avoid problem :D

How to call touchesBegan in a sub-classed UIView in iOS 8?

I want touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event to be called in a sub-classed UIView.
AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:[[UIViewController alloc] init]];
CGRect firstFrame = self.window.bounds;
HypnosisView *firstView = [[SubClassedView alloc] initWithFrame:firstFrame];
[self.window addSubview:firstView];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
SubClassedView.h:
#import <UIKit/UIKit.h>
#interface SubClassedView : UIView
#end
SubClassedView.m:
#import "SubClassedView.h"
#implementation SubClassedView
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(#"Here!");
}
#end
When I touched the screen, the console didn't output "Here!" as I thought it should.
I use the newest Xcode 7 beta 5.
How can I get touchesBegan to be called in the right way?
Thank you very much.
You're adding your HypnosisView as the subview of the window, rather than as a subview of the root view controller's view. Your root view controller should be a UIViewController subclass so that you can modify its behaviour to build your app's navigation flow.
Subclass UIViewController, and add your HypnosisView as a subview in its view hierarchy:
#interface MyViewController : UIViewController
#property(nonatomic, strong) HypnosisView *hypnosisView;
#end
#implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.hypnosisView = [[HypnosisView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:hypnosisView];
}
#end
Then in your app delegate, set your view controller subclass to be the root view controller:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
MyViewController *myVC = [[MyViewController alloc] init];
[self.window setRootViewController:myVC];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
This is quite an old-school method of doing things though. Is there any reason you're not using storyboards to build your interface?

How to present View Controller modally on app launch?

I've created a screen that ONLY appears the first time that my app is launched; it works great. However, I'd like to present this screen modally on top of my root view controller (EditorsNoteViewController being the screen I want to present modally on first launch). Does anyone know how I would do this? Here is what I have so far:
Appdelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"HasLaunchedOnce"])
{
NSLog(#"not first launch");
self.viewController = [[UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil] instantiateViewControllerWithIdentifier:#"articlesNav"];
self.window.rootViewController = self.viewController;
}
else
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"HasLaunchedOnce"];
[[NSUserDefaults standardUserDefaults] synchronize];
self.viewController = [[UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil] instantiateViewControllerWithIdentifier:#"articlesNav"];
self.window.rootViewController = self.viewController;
EditorsNoteViewController *vc = [[EditorsNoteViewController alloc]init];
[self.viewController.navigationController presentViewController:vc animated:YES completion:nil];
}
[self.window makeKeyAndVisible];
return YES;
}
I figured out that you'll have to call
[self.window makeKeyAndVisible];
before presenting the view controller
I have read about and encountered this issue many times. A way to completely get around this issue (without any flickering or warnings) is to consider a custom container view controller that will contain your root view controller and your modally presented view controller, as child view controllers. The container view controller can then transition between the two with custom animations, with a very similar effect as present/dismiss.
Let's consider the following container view controller :
#implementation ContainerViewController {
NSMutableArray* stack;
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
stack = [NSMutableArray new];
}
return self;
}
- (void) pushViewController:(UIViewController*) viewController {
UIViewController* currentViewController = [stack lastObject];
[stack addObject:viewController];
if (self.isViewLoaded) {
[self addChildViewController:viewController];
[currentViewController willMoveToParentViewController:nil];
viewController.view.frame = CGRectOffset(self.view.bounds, 0, self.view.bounds.size.height);
[self transitionFromViewController:currentViewController toViewController:viewController duration:0.3 options:kNilOptions animations:^{
viewController.view.frame = self.view.bounds;
} completion:^(BOOL finished) {
[viewController didMoveToParentViewController:self];
[currentViewController removeFromParentViewController];
}];
}
}
- (void) popViewController {
UIViewController* currentViewController = [stack lastObject];
[stack removeLastObject];
if (self.isViewLoaded) {
UIViewController* viewController = [stack lastObject];
[self addChildViewController:viewController];
[currentViewController willMoveToParentViewController:nil];
[self transitionFromViewController:currentViewController toViewController:viewController duration:0.3 options:kNilOptions animations:^{
[self.view sendSubviewToBack:viewController.view];
currentViewController.view.frame = CGRectOffset(self.view.bounds, 0, self.view.bounds.size.height);
} completion:^(BOOL finished) {
[viewController didMoveToParentViewController:self];
[currentViewController removeFromParentViewController];
}];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
UIViewController* viewController = [stack lastObject];
[self addChildViewController:viewController];
[self.view addSubview:viewController.view];
[viewController didMoveToParentViewController:self];
}
#end
In your AppDelegate, you can then have something along those lines :
ContainerViewController* viewController = [ContainerViewController new];
[viewController pushViewController: [RootViewController new];
if ([self shouldPresentModalViewController]) {
[viewController pushViewController: [ModalViewController new];
}
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
Somewhere in the modal view controller, you can use the following code to dismiss it:
[((ContainerViewController*) self.parentViewController) popViewController];
Assuming that you have created your EditorsNoteViewController in a storyboard, you should initialise it like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
EditorsNoteViewController *vc = (EditorsNoteViewController*)[storyboard instantiateViewControllerWithIdentifier:#"EditorsNoteOrWhateverIdentifierYouChose"];
Try to check your NSUserDefaults in your RootViewController -viewDidLoad, and if it is the first time, present the new UIViewController there (So that you don't need to mess around with your AppDelegate).
If you want to present it animated, you can do it in -viewDidAppear instead of -viewDidLoad.

iPad Landscape Mode - How To Add Two Splash Screen

I have successfully finished my app after months of coding. Now I'm trying to add the initial Splash Screen images to my app. How do i proceed? I have two images: one is the company logo and the other is the app logo (these splash screens are to hide the loading time). I have looked every where for an possible answer, but ended up with no solution. When i name a single pic Default-Landscape.png and run the Ipad App - The image is showing until the main view controller loads up, but I want the first image to be displayed for 1 second and fade out to the second image which will also be displayed for 1 second after which the main view controller appears(the original application page).
I have checked various answers, but none seems to work - Xcode 4 and iPad2 splash screen issue
Setting splash images for portrait and landscape mode - IPad
etc..
Here is my code for the same - AppDelegate.h
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSArray *docDir=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath=[docDir objectAtIndex:0];
databasePath=[docPath stringByAppendingPathComponent:#"something.sqlite"];
//databasePath1=[docPath stringByAppendingPathComponent:#"something.sqlite"];
NSString *bundlePath=[[NSBundle mainBundle]pathForResource:#"something" ofType:#"sqlite"];
NSFileManager *mngr=[NSFileManager defaultManager];
if ([mngr fileExistsAtPath:databasePath]) {
NSLog(#"File Exists");
}
else
{
[mngr copyItemAtPath:bundlePath toPath:databasePath error:NULL];
NSLog(#"File Created");
}
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
How should I proceed now? Should I create a new class like (splashScreen 1 and splashScreen 2) with uiImageView and change the didFinishLaunchingWithOptions method? Any help would be greatly appreciated.
Updated: 30 May 2013
Appdelegate.h
#import <UIKit/UIKit.h>
#import "sqlite3.h"
#import "FBInteract.h"
#import "splashScreen1.h"
sqlite3 *dbHandler;
NSString *databasePath;
#class ViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *naviObj;
}
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) ViewController *viewController;
#property (strong, nonatomic) UINavigationController *naviObj;
#end
Appdelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
splashScreen1 *splashScreen1PageObj=[[splashScreen1 alloc]init];
self.naviObj = [[UINavigationController alloc]initWithRootViewController:splashScreen1PageObj];
self.window.rootViewController = self.naviObj;
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:NO];
[self.window makeKeyAndVisible];
return YES;
}
splashScreen1.h and splashScreen2.h
#import <UIKit/UIKit.h>
#import "splashScreen2.h"
#interface splashScreen1 : UIViewController
{
IBOutlet UIImageView *imgObjSplashImage; // IBOutlet UIImageView *objSplashImage; - in splashScreen2.h
}
-(void)hideSplash;
-(void)navigationToMain;
-(void)showSplash;
#end
splashScreen1.m and splashScreen2.m
- (void)viewDidLoad
{
// Do any additional setup after loading the view from its nib.
[NSTimer scheduledTimerWithTimeInterval:1.2 target:self selector:#selector(showSplash) userInfo:nil repeats:NO];
self.navigationController.navigationBarHidden=YES;
[imgObjSplashImage setAlpha:0]; //objSplashImage instead of imgObjSplashImage in splashScreen2
[super viewDidLoad];
}
-(void)showSplash{
[UIImageView beginAnimations:nil context:NULL];
[UIImageView setAnimationDuration:1.2];
[imgObjSplashImage setAlpha:1]; //objSplashImage instead of imgObjSplashImage in splashScreen2
[UIImageView commitAnimations];
[NSTimer scheduledTimerWithTimeInterval:2.4 target:self selector:#selector(hideSplash) userInfo:nil repeats:NO];
}
-(void)hideSplash{
[UIImageView beginAnimations:nil context:NULL];
[UIImageView setAnimationDuration:1.4];
[imgObjSplashImage setAlpha:0]; //objSplashImage instead of imgObjSplashImage in splashScreen2
[UIImageView commitAnimations];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(navigationToMain) userInfo:nil repeats:NO];
}
#pragma mark
#pragma mark - Navigation Coding
-(void)navigationToMain {
//[self dismissModalViewControllerAnimated:YES];
[self dismissViewControllerAnimated:NO completion:Nil];
ViewController *ViewControllerPageObj=[[ViewController alloc]init];
[self.navigationController pushViewController:ViewControllerPageObj animated:NO];
[ViewControllerPageObj release];
//[self presentViewController:ViewControllerPageObj animated:NO completion:Nil];
}
-(void)viewWillAppear:(BOOL)animated {
self.navigationController.navigationBarHidden=YES;
}
The problem is ViewController(main ViewController) is not loading...I'm getting error saying "message sent to deallocated instance" in viewDidLoad part of ViewController.m
RootViewController -> splashScreen1 -> splashScreen2 is working fine(with all the animation fading in and out) but the final ViewController is not loading..
For this you definitely want another VC, lets call it StartViewController. Add there an imageView, block rotation and setTimer:
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(moveOnAndChangeVC:) userInfo:nil repeats:NO];
and if you develop NavigationControl app you should also change rootVC for example:
+(void)replaceRootVCWithVC:(id)vc {
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[[sharedAppDelegate navigationController] viewControllers]];
if(![viewControllers isEmpty])
[viewControllers replaceObjectAtIndex:0 withObject:vc];
else
[viewControllers addObject:vc];
[[sharedAppDelegate navigationController] setViewControllers:viewControllers];
}
EDIT:
You should change in your appDelegate line with initializer:
self.viewController = [[[StartViewController alloc] initWithNibName:#"StartViewController" bundle:nil] autorelease];
This should call your VC as a rootVC.
Then in StartViewController.m you should recognize device (this is a iPad only app, right? not universal) and orientation:
+(NSString*)recognizeDeviceAndOrientation {
NSMutableString * returnString;
if([StartViewController deviceInterfaceOrientation] == UIInterfaceOrientationLandscapeLeft || [StartViewController deviceInterfaceOrientation] == UIInterfaceOrientationLandscapeRight) {
returnString = #"Default-Landscape";
} else {
returnString = #"Default-Portrait";
}
if([UIScreen mainScreen].scale == 2.0)
return [NSString stringWithFormat:#"%#%#",returnString,#"#2x"];;
else
return returnString;
}
+(UIInterfaceOrientation)deviceInterfaceOrientation {
return [[UIApplication sharedApplication] statusBarOrientation];
}
This will return you a string with DefaultScreen name with proper orientation. If you handling only one orientation forget about it.
Then in viewDidLoad you add imageView:
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *imageView = [[[UIImageView alloc] initWithImage:[StartViewController recognizeDeviceAndOrientation]] autorelease];
[imageView setFrame:self.frame];
[imageView setContentMode:UIViewContentModeScaleToFill];
[self.view addSubview:imageView];
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(moveOnAndChangeVC:) userInfo:nil repeats:NO];
}
This will call a timer and set imageView.
-(IBACtion)moveOnAndChangeVC:(id)sender {
//if you using navigation app
ViewController *vc = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
[self.navigationController pushViewController:vc animated:NO];
}
This will work. And then if you want to get rid of "back button" just change a rootView Controller like i said in the beginning. Do it in your ViewController class.

iOS App UIView rotating, content is not

I'm currently building an iOS app, and the only supported orientations are landscape left and right. I've specified this in several ways:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation); //iOS 5 compatibility.
}
-(NSInteger)supportedInterfaceOrientations:(UIWindow *)window{
return UIInterfaceOrientationMaskLandscape; //iOS 6
}
-(BOOL)shouldAutorotate{
return YES;
}
And I've specified the supported orientations as only the landscape ones in the app's Info.plist. When I run the app on my device (or even in the simulator), I know that the root view is in landscape orientation (switcher is on the long side of the screen, as is notification center), however the content still originates from the top left corner of the screen, as if in portrait mode, not the bottom left or top right, like I want it to be. I have no idea what could be causing the content not to rotate with the parent view, as this code worked on iOS 5, but is not on iOS 6.
EDIT: Here's a screenshot.
EDIT: Here's my main.m:
#import <UIKit/UIKit.h>
int main(int argc, char **argv) {
NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
int ret = UIApplicationMain(argc, argv, #"ClockApplication", #"ClockApplication");
[p drain];
return ret;
}
And here's my ClockApplication.mm:
#import "RootViewController.h"
#interface ClockApplication: UIApplication <UIApplicationDelegate> {
UIWindow *_window;
RootViewController *_viewController;
}
#property (nonatomic, retain) UIWindow *window;
#end
#implementation ClockApplication
#synthesize window = _window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_viewController = [[RootViewController alloc] init];
[_window addSubview:_viewController.view];
[_window makeKeyAndVisible];
}
- (void)dealloc {
[_viewController release];
[_window release];
[super dealloc];
}
#end
Try changing your method from this
-(NSInteger)supportedInterfaceOrientations:(UIWindow *)window{
}
to this
-(NSUInteger)supportedInterfaceOrientations{
}
EDIT
Try calling your view inside a navigationcontroller like this:
UIViewController *yourViewController = [[UIViewController alloc] init];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:yourViewController];
nc.navigationBarHidden = YES;
[self.navigationController presentModalViewController:nc animated:NO];
[self.navigationController dismissModalViewControllerAnimated:NO];
EDIT
#import "RootViewController.h"
#interface ClockApplication: UIApplication <UIApplicationDelegate> {
UIWindow *_window;
RootViewController *_viewController;
}
#property (nonatomic, retain) UIWindow *window;
#end
#implementation ClockApplication
#synthesize window = _window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:_viewController];
nc.navigationBarHidden = YES;
_window.rootViewController = nc;
[_window makeKeyAndVisible];
}
- (void)dealloc {
[_viewController release];
[_window release];
[super dealloc];
}
#end
Try to add:
_window.rootViewController = _viewController;
EDIT: Anyway your code looks like using "deprecated" style. I would suggest to set up a new project for iOS6 and use its template. It was working on iOS5 but iOS changes.
Only the rootViewController of your UIWindow will receive rotation events.
[_window setRootViewController:_rootViewController];
Check out the apple technical notes.

Resources