Reputation: 283
It works perfect fine when starting in portrait and also works when you rotate from portrait to landscape and back.
It does not work when starting in landscape. But then it works when you rotate from landscape to portrait and back.
In landscape starting mode, the screen does not respond with any touch where screen coordinateX greater than 768.
What happens in code is, I use status bar orientation to determine original orientation and rotate each view manually. The views display correctly but does not receive touch properly.
Then my root view controller will get called when ipad start rotating with:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
which will rotate every subviews.
Root controller:
- (void)loadView {
self.view = [[UIView alloc]init ];
//initialize child views
[self willRotateToInterfaceOrientation:0 duration:0];
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if ([model isLandscape]) {
self.view.frame = CGRectMake(0, 0, 1024, 768-80);
}
else {
self.view.frame = CGRectMake(0, 0, 768, 1024-80);
}
//rotate child views
}
My code [model isLandscape] works so I don't need to provide details as to how it works but here are the code anyway:
- (bool)isLandscape {
if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
return true;
else
return false;
}
-(id) init
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIInterfaceOrientation curOrientation = [[UIDevice currentDevice] orientation];
if (curOrientation == UIDeviceOrientationPortrait ||
curOrientation == UIDeviceOrientationPortraitUpsideDown ||
curOrientation == UIDeviceOrientationLandscapeLeft ||
curOrientation == UIDeviceOrientationLandscapeRight)
{
orientation = curOrientation;
((AppDelegate*)([UIApplication sharedApplication].delegate)).savedOrientationForRestart = orientation;
NSLog(@"changed");
}
}
-(void)validateOrientation { //first time when initializing orientation
UIInterfaceOrientation curOrientation = [[UIDevice currentDevice] orientation];
if (curOrientation != UIDeviceOrientationPortrait &&
curOrientation != UIDeviceOrientationPortraitUpsideDown &&
curOrientation != UIDeviceOrientationLandscapeLeft &&
curOrientation != UIDeviceOrientationLandscapeRight)
{
orientation = [[UIApplication sharedApplication] statusBarOrientation];
}
}
Upvotes: 3
Views: 511
Reputation: 283
OK. so it turns out among the tens of backgrounds and layers some were not rotated to landscape/portrait correctly...it was extremely hard to debug this issue...
in the end, I hooked up a touch debugger to see which views are receiving touch correctly and which are not...
extremely helpful! Just use the UIWindow subclass below instead of UIWindow in your code, should work.
#import <UIKit/UIKit.h>
@interface MyUIWindow : UIWindow {
}
-(void)rotate;
@end
and
#import "MyUIWindow.h"
@implementation MyUIWindow
-(id) init{
self = [super init];
if(self)
{
}
return self;
}
- (void)sendEvent:(UIEvent *)event {
[super sendEvent:event];
NSSet *touches = [event allTouches];
if (touches.count != 1)
return;
UITouch *touch = touches.anyObject;
UIView * view = touch.view;
NSLog(NSStringFromClass([touch.view class])); //this prints out touch view
}
@end
Upvotes: 0