My modal view does not rotate - ios

I encounter an issue with a modal view display. My first view rotate very well. The controller of the modal view implements the "ShouldAutorotationToInterfaceRotation" method but when I rotate the device or simulator the modal view doesn't rotate.
I've added some comments to check if the first view detects the rotation events instead of the modal view but no, it doesn't get the event.
Do you have a clue?

You will need to subscribe to NSNotificationCenter to receive rotation events for your modal view. Then, if you want to keep the modal view orientated correctly relative to the bottom view, one solution would be to transform the view. Here's one implementation:
Put this in the viewDidLoad and save the original orientation as an angle:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification object:nil];
int initialOrientation = [[UIApplication sharedApplication] statusBarOrientation];
if (initialOrientation == UIDeviceOrientationPortrait)
initialAngle = 0.0;
else if (initialOrientation == UIDeviceOrientationLandscapeRight)
initialAngle = 90.0;
else if (initialOrientation == UIDeviceOrientationPortraitUpsideDown)
initialAngle = 180.0;
else if (initialOrientation == UIDeviceOrientationLandscapeLeft)
initialAngle = 270.0;
currentAngle = initialAngle;
Then define the function orientationChanged:(NSNotification *)notification with code to rotate correctly relative to the initial orientation:
int newOrientation = [[notification object] orientation];
if (newOrientation == UIDeviceOrientationPortrait)
desiredAngle = 0.0;
else if (newOrientation == UIDeviceOrientationLandscapeRight)
desiredAngle = 90.0;
else if (newOrientation == UIDeviceOrientationPortraitUpsideDown)
desiredAngle = 180.0;
else if (newOrientation == UIDeviceOrientationLandscapeLeft)
desiredAngle = 270.0;
if(desiredAngle != currentAngle)
{
CGAffineTransform rotate = CGAffineTransformMakeRotation(M_PI * (-desiredAngle+initialAngle) / 180.0);
CGAffineTransform translate = CGAffineTransformMakeTranslation(0, 0);
[[self releaseView] setTransform:CGAffineTransformConcat(translate, rotate)];
}
currentAngle = desiredAngle;

Related

Rotate the view only in ios

My application is only supported on Portrait mode. I have requirement that need to rotate the particular UIView only according to the device orientation.
Can you please help me?
if (interfaceOrientation == UIInterfaceOrientationPortrait) {
// set your view frame work for portrait mode
}
else {
// set new frame of view for landscape mode.
}
Hope you get the idea.
thanks
Add below give code in your viewdidload or init
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(deviceOrientationDidChange:) name: UIDeviceOrientationDidChangeNotification object: nil];
In deviceOrientationDidChange function you will get the device orientation,according to this you can update your view
- (void)deviceOrientationDidChange:(NSNotification *)notification {
//Obtain current device orientation
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
//Do my thing
}
After the long try I found the answer using CGAffineTransform ..
- (void)deviceOrientationDidChange:(NSNotification *)notification {
//Obtain current device orientation
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
CGFloat angle;
switch (orientation) {
case UIDeviceOrientationPortraitUpsideDown:
angle = M_PI;
break;
case UIDeviceOrientationLandscapeRight:
angle = - M_PI_2;
break;
case UIDeviceOrientationLandscapeLeft:
angle = M_PI_2;
break;
case UIDeviceOrientationPortrait:
default:
angle = 0.f;
break;
}
animationView.transform= CGAffineTransformMakeRotation(angle);
animationView.frame = self.view.frame;
}

change screen rotation of app extension in objective c

How do I lock from rotating screen, I want my app extension to be only in portrait mode.
When I'm using my extension inside Photos my I can rotate the screen to landscape.
thanks
You have to choice:
1- Set landscape and portrait as supported interface orientation in the project, and then for each ViewController, you will override the supported interface orientation;
2- Set only portrait mode in the project, and in the ViewController you need it, you can make a 90 degree rotation
self.view.transform = CGAffineTransformMakeRotation(M_PI_2);
EDIT: so you can do this. Set your controller as observer for the keyPath UIDeviceOrientationDidChangeNotification. Then:
-(void)changedOrientation: (NSNotification *)note
{
if (note)
{
UIDevice *dev = (UIDevice *)note.object;
if ([dev orientation] == UIInterfaceOrientationLandscapeRight)
{
self.view.transform = CGAffineTransformMakeRotation(M_PI_2);
}
else if ([dev orientation] == UIInterfaceOrientationPortrait)
{
self.view.transform = CGAffineTransformIdentity;
}
else if ([dev orientation] == UIInterfaceOrientationPortraitUpsideDown)
{
self.view.transform = CGAffineTransformIdentity;
}
else if ([dev orientation] == UIInterfaceOrientationLandscapeLeft)
{
self.view.transform = CGAffineTransformMakeRotation(-M_PI_2);
}
}
}

set the frame size when orientation is changed in ios

I want to change the orientation of a view in ios 6. When the orientation is changed, I want to set the frame size of the views.
My Sample Code for orientation change:
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSInteger)supportedInterfaceOrientations
{
NSInteger mask = 0;
intOrientation = [[UIApplication sharedApplication] statusBarOrientation];
if(intOrientation == UIInterfaceOrientationPortrait || intOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
mask |= UIInterfaceOrientationMaskPortrait;
} else
if(intOrientation == UIInterfaceOrientationLandscapeLeft)
{
mask |= UIInterfaceOrientationMaskLandscapeLeft;
}
}
NSLog (#"mask %d",mask);
return mask;
}
// Here now mask value is 2 because my default mode is portrait.
Now when I change my orientation to landscape, I want to set the frame size. Please guide me on how to do that.
ok..Can I set the frame size for the view like dis by taking the version and comparing it in viewdidLoad:
orientation = [[UIDevice currentDevice] orientation];
NSString *reqSysVer = #"6.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
NSLog (#"ios version %#",currSysVer);
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
{
if (orientation == UIInterfaceOrientationMaskPortrait) {
self.view.frame = CGRectMake(0, 0, 1000, 800);
self.tableView1.frame = CGRectMake(1, 0, 764,510);
}
else if (orientation == UIInterfaceOrientationMaskLandscapeLeft)
{
self.view.frame = CGRectMake(0, 0, 1300, 370);
self.tableView1.frame = CGRectMake(0, 0, 1300, 370);
self.view.backgroundColor = [UIColor blackColor];
}
}
you can get a notification when the interface orientation changes:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
and add a function like:
- (void)didRotate:(NSNotification *)notification {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientation...)
{
// add some code
}
}
The best solution would be to use Auto Layout or Constraints, I think.
But you can also check for the device orientation using
[UIDevice currentDevice].orientation
or check the size (e.g. for iPhone 5 support) using
[UIScreen mainScreen].bounds.size.height
// Update:
Consider that on iOS 8 width and height were switched in landscape. So witdh and height are always depending on the orientation now.

How to rotate landscape only with Cocos2d

This is my last step of the app, everything else is done.
I'm using cocos2d, and no matter what I do, I cannot get the app to rotate. It HAS to only rotate landscape with the way my app is set up.
Here's my GameConfig.h
#ifndef __GAME_CONFIG_H
#define __GAME_CONFIG_H
//
// Supported Autorotations:
// None,
// UIViewController,
// CCDirector
//
#define kGameAutorotationNone 0
#define kGameAutorotationCCDirector 1
#define kGameAutorotationUIViewController 2
//
// Define here the type of autorotation that you want for your game
//
#define GAME_AUTOROTATION kGameAutorotationUIViewController
#endif // __GAME_CONFIG_H
And my AppDelegate's applicationDidFinishLaunching method,
#if GAME_AUTOROTATION == kGameAutorotationUIViewController
//[director setDeviceOrientation:kCCDeviceOrientationPortrait];
[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
#else
// [director setDeviceOrientation:kCCDeviceOrientationPortrait];
[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
#endif
And RootController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
//
// Assuming that the main window has the size of the screen
// BUG: This won't work if the EAGLView is not fullscreen
///
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGRect rect = CGRectZero;
if(toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
rect = screenRect;
else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
rect.size = CGSizeMake( screenRect.size.height, screenRect.size.width );
CCDirector *director = [CCDirector sharedDirector];
EAGLView *glView = [director openGLView];
float contentScaleFactor = [director contentScaleFactor];
if( contentScaleFactor != 1 ) {
rect.size.width *= contentScaleFactor;
rect.size.height *= contentScaleFactor;
}
glView.frame = rect;
}
In the Info.plist I have both landscape orientations in the supported list.
What am I doing wrong?
Thanks
Try to add this line
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
to your applicationDidFinishLaunching: method

CABasicAnimation is ignored during rotation

I have a UIView that in the layoutSubviews method repositions its subviews based on the orientation of the iPad. Within the layoutSubviews method I have a CABasicAniamtion that is supposed to animate the repositioning of the subviews. The animations are set to specific duration but this duration is being ignored and repositioning happens immediately. I know the animations are firing because I am seeing the AnimationDidStart and AnimationDidStop methods being fired. I know this has something to do with the CALayers of the UIView but I can not find anything on the web to explain how to fix this. Any help would be appreciated.
if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
{
NSLog(#"Orientation: Portrait");
//Hide icon
CABasicAnimation *iconAnimation = [CABasicAnimation animationWithKeyPath:#"position"];
iconAnimation.fromValue = [NSValue valueWithCGPoint:[iconImageView center]];
iconAnimation.toValue = [NSValue valueWithCGPoint:iconThinPosition];
iconAnimation.duration = 2.7f;
iconAnimation.autoreverses = NO;
iconAnimation.repeatCount = 1;
iconAnimation.delegate = self;
[iconImageView.layer addAnimation:iconAnimation forKey:#"position"];
//[iconImageView setCenter:iconThinPosition];
[iconImageView.layer setPosition:iconThinPosition];
//[iconImageView setTransform: CGAffineTransformIdentity];
CABasicAnimation *textAnimation = [CABasicAnimation animationWithKeyPath:#"position"];
textAnimation.fromValue = [NSValue valueWithCGPoint:[textImageView center]];
textAnimation.toValue = [NSValue valueWithCGPoint:textThinPosition];
textAnimation.duration = 2.7f;
textAnimation.autoreverses = NO;
textAnimation.repeatCount = 1;
textAnimation.delegate = self;
[textImageView.layer addAnimation:textAnimation forKey:#"position"];
[textImageView.layer setPosition:textThinPosition];
}
else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)
{
NSLog(#"Orientation: Landscape");
// Show Icon
CABasicAnimation *iconAnimation = [CABasicAnimation animationWithKeyPath:#"position"];
iconAnimation.fromValue = [NSValue valueWithCGPoint:[iconImageView center]];
iconAnimation.toValue = [NSValue valueWithCGPoint:iconShownPosition];
iconAnimation.duration = 2.7f;
iconAnimation.autoreverses = NO;
iconAnimation.repeatCount = 1;
iconAnimation.delegate = self;
[iconImageView.layer addAnimation:iconAnimation forKey:#"position"];
[iconImageView.layer setPosition:iconShownPosition];
CABasicAnimation *textAnimation = [CABasicAnimation animationWithKeyPath:#"position"];
textAnimation.fromValue = [NSValue valueWithCGPoint:[textImageView center]];
textAnimation.toValue = [NSValue valueWithCGPoint:textShownPosition];
textAnimation.duration = 2.7f;
textAnimation.autoreverses = NO;
textAnimation.repeatCount = 1;
textAnimation.delegate = self;
[textImageView.layer addAnimation:textAnimation forKey:#"position"];
[textImageView.layer setPosition:textShownPosition];
}
}
I wonder if it isn't being ignored so much as there is already an animation transaction in progress when your layoutSubviews gets called. One thing you could try to confirm this is to override -didRotateFromInterfaceOrientation and call your layoutSubviews from there. See if your views animate then.
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// [self layoutSubviews];
// Give it a second to settle after the rotation and then call
// layoutSuviews explicitly.
[self performSelector:#selector(layoutSubviews) withObject:nil afterDelay:1.0f];
}
Another thing to think about is that since you are only animating the position of the UIView's layer, you could use UIView animations instead of explicit animation. Something like:
if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
{
NSLog(#"Orientation: Portrait");
//Hide icon
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.7f];
[iconImageView setCenter:iconThinPosition];
[textImageView setCenter:textThinPosition];
[UIView commitAnimations];
}
else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)
{
NSLog(#"Orientation: Landscape");
// Show Icon
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.7f];
[iconImageView setCenter:iconShownPosition];
[textImageView setCenter:textShownPosition];
[UIView commitAnimations];
}

Resources