I have a UIViewController that has an image view and a toolbar. I would like the toolbar to rotate, but the imageview to stay as it is. Is this possible?
Yes this is possible, but requires manual handling of rotate events.
In viewDidLoad, add
// store the current orientation
currentOrientation = UIInterfaceOrientationPortrait;
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector: #selector(receivedRotate:) name: UIDeviceOrientationDidChangeNotification object: nil];
if(currentOrientation != self.interfaceOrientation) {
[self deviceInterfaceOrientationChanged:self.interfaceOrientation];
}
and don't forget to deregister events when the controller is removed.
Then add a method for rotates:
// This method is called by NSNotificationCenter when the device is rotated.
-(void) receivedRotate: (NSNotification*) notification
{
NSLog(#"receivedRotate");
UIDeviceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
if(interfaceOrientation != UIDeviceOrientationUnknown) {
[self deviceInterfaceOrientationChanged:interfaceOrientation];
} else {
NSLog(#"Unknown device orientation");
}
}
and finally the rotate method
- (void)deviceInterfaceOrientationChanged:(UIInterfaceOrientation)interfaceOrientation {
if(interfaceOrientation == currentOrientation) {
NSLog(#"Do not rotate to current orientation: %i", interfaceOrientation);
} else if(interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
NSLog(#"Do not rotate to UIInterfaceOrientationPortraitUpsideDown");
} else if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
NSLog(#"Do not rotate to UIInterfaceOrientationLandscapeLeft");
} else {
if(!isRotating)
{
isRotating = YES;
if(currentOrientation == UIInterfaceOrientationPortrait && interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
NSLog(#"Rotate to landscape");
// rotate to right top corner
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
// do your rotation here
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationDoneShowCaption:finished:context:)];
[UIView commitAnimations];
} else if(currentOrientation == UIInterfaceOrientationLandscapeRight && interfaceOrientation == UIInterfaceOrientationPortrait) {
// etc
}
isRotating = NO;
} else {
NSLog(#"We are already rotating..");
}
}
currentOrientation = interfaceOrientation;
}
Note that I do not allow for rotates in some directions, you might.
In addition, you need to make your components resizable / able to rotate.
Edit Consider using block-based animations instead and set the isRotation = NO in the completion block.
Related
i have 4 classes (class1, class2, class3 & class4) for class1, class2 & class3 i have all modes support (Landscape & Portrait). But for class 4 i need only Portrait support. Issue here is when i load class4 in Landscape mode its showing view in landscape, when i rotate class4 to Portrait mode once, its not rotating to landscape again. I want class4 to load in portrait only weather i come load class 4 in portrait or landscape mode.
i tried this
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation != UIInterfaceOrientationPortrait)
{
return NO;
}
}
Please let me know, how to proceed
Seems like all you need to do is return a YES for everything but portrait orientation.
How about:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// b.t.w., there is also an upside down portrait constant
// which is UIInterfaceOrientationPortraitUpsideDown
if (interfaceOrientation != UIInterfaceOrientationPortrait)
{
return NO;
}
return YES;
}
B.T.W., according to the public documentation for shouldAutorotateToInterfaceOrientation:, this API is deprecated as of iOS 6.0. If you care about your app's survivability for the future, you may want to consider doing something different.
Try this
-(void)orientationChanged:(NSNotification *)object{
NSLog(#"orientation change");
UIDeviceOrientation deviceOrientation = [[object object] orientation];
if(deviceOrientation == UIInterfaceOrientationLandscapeLeft ||deviceOrientation == UIInterfaceOrientationLandscapeRight)
{
Bg.image=[UIImage imageNamed:#"splashBgL.png"]; ///Lendscape Background
Bg.frame=CGRectMake(0, 0, 480, 320);
self.view.frame=CGRectMake(0, 0, 480, 320);
}
else{
Bg.image=[UIImage imageNamed:#"splashBg.png"];///Protrait Background
Bg.frame=CGRectMake(0, 0, 320, 480);
}
}
-(void)landscapeLeftOrientation{
CGRect contentRect = CGRectMake(0, 0, 480, 320);;
self.view.bounds = contentRect;
}
-(void)landscapeRightOrientation{
CGRect contentRect = CGRectMake(0, 0, 480, 320);
self.view.bounds = contentRect;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:)name:#"UIDeviceOrientationDidChangeNotification" object:nil];
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self landscapeLeftOrientation];
}
i want resize a UINavigationBar and a UITableView connected with .xib file when the orientation change in my iPad application, now i'll do this:
- (void)viewWillAppear:(BOOL)animated {
UIInterfaceOrientation currentOrientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIInterfaceOrientationIsLandscape(currentOrientation)) {
[self.seriesTable setFrame:CGRectMake(self.seriesTable.frame.origin.x, self.seriesTable.frame.origin.y, 425, self.seriesTable.frame.size.height)];
[self.myNavBar setFrame:CGRectMake(self.myNavBar.frame.origin.x, self.myNavBar.frame.origin.y, 425, self.myNavBar.frame.size.height)];
} else {
[self.seriesTable setFrame:CGRectMake(self.seriesTable.frame.origin.x, self.seriesTable.frame.origin.y, 670, self.seriesTable.frame.size.height)];
[self.myNavBar setFrame:CGRectMake(self.myNavBar.frame.origin.x, self.myNavBar.frame.origin.y, 670, self.myNavBar.frame.size.height)];
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
NSLog(#"landscape");
[self.seriesTable setFrame:CGRectMake(self.seriesTable.frame.origin.x, self.seriesTable.frame.origin.y, 425, self.seriesTable.frame.size.height)];
[self.myNavBar setFrame:CGRectMake(self.myNavBar.frame.origin.x, self.myNavBar.frame.origin.y, 425, self.myNavBar.frame.size.height)];
} else {
NSLog(#"portrait");
//[self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, 678, self.view.frame.size.height)];
[self.seriesTable setFrame:CGRectMake(self.seriesTable.frame.origin.x, self.seriesTable.frame.origin.y, 670, self.seriesTable.frame.size.height)];
[self.myNavBar setFrame:CGRectMake(self.myNavBar.frame.origin.x, self.myNavBar.frame.origin.y, 670, self.myNavBar.frame.size.height)];
}
}
when the app start the frame size is correct, but when i change orientation go in the will rotate.. method but the frame don't change the size, and to resize it i have to switch to another UITabBar tab and then return to that view and obviously pass in the viewwillappear method and resize the view, but when the orientation change nothing happen, how i can do?
Following code this will help you to change the Webview size based on the Orientation
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector (orientationchangefunction:) name:UIDeviceOrientationDidChangeNotification object:nil];
[self orientationchngfn];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(interfaceOrientation == UIInterfaceOrientationPortrait)
{
orientseason=0;
}
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
orientseason=1;
}
if(interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
orientseason=1;
}
if(interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
orientseason=0;
}
if(orientseason==0)
{
}
else if(orientseason==1)
{
}
return YES;
}
-(void) orientationchangefunction:(NSNotification *) notificationobj
{
[self performSelector:#selector(orientationchngfn) withObject:nil afterDelay:0.0];
}
-(void) orientationchngfn
{
UIDeviceOrientation dorientation =[UIDevice currentDevice].orientation;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if(UIDeviceOrientationIsPortrait(dorientation))
{
orientseason=0;
}
else if (UIDeviceOrientationIsLandscape(dorientation))
{
orientseason=1;
}
if(orientseason==0)
{
webview4Html.frame=CGRectMake(5, 44, 310, 419);
}
else if(orientseason==1)
{
webview4Html.frame=CGRectMake(5, 44, 470, 276);
}
}
else {
if(UIDeviceOrientationIsPortrait(dorientation))
{
orientseason=0;
}
else if (UIDeviceOrientationIsLandscape(dorientation))
{
orientseason=1;
}
if(orientseason==0)
{
webview4Html.frame=CGRectMake(5, 44, 758, 940);
}
else if(orientseason==1)
{
webview4Html.frame=CGRectMake(5, 44, 1014, 684);
}
}
}
Assuming the resizing isnt too strange, this would be much easier done with autoresizing masks
I detect screen change orientation with :
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(detectOrientation) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
and when it call i call this method:
if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
[md changeToBigNowPlaying:YES withLayer:avPlayerLayer];
}else{
[md changeToBigNowPlaying:NO withLayer:avPlayerLayer];
}
and in this function i do this stuff:
-(void)changeToBigNowPlaying:(BOOL)flag withLayer:(AVPlayerLayer*)layer{
if (flag) {
//To portrait
[landVC.view removeFromSuperview];
[layer removeFromSuperlayer];
[self.window addSubview:tab.view];
}else {
//To landscape
[tab.view removeFromSuperview];
[landVC setUpNewLayer:layer];
[self.window addSubview:landVC.view];
}
}
and this is the explanation :
I have tabbar with viewcontroller,and when i detect that the user rotate the screen to landscape i remove the tabbar and add a UIViewController(landVC) and when i rotate it to portrait again i remove the landvc and add again the tabbar.
my problem is when i rotate first to UIInterfaceOrientationLandscapeLeft so it show me the screen in UIInterfaceOrientationLandscapeRight. but when i rotate to UIInterfaceOrientationLandscapeRight first i see the screen like it should and when i rotate from this situation to UIInterfaceOrientationLandscapeLeft i see the screen good too.
any idea why i have a problem when i rotate to UIInterfaceOrientationLandscapeLeft and i see the landVc in UIInterfaceOrientationLandscapeRight
In landVC UIViewController i implement:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(interfaceOrientation == UIInterfaceOrientationLandscapeRight){
return YES;
}else if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
return YES;
}else {
return NO;
}
}
Edit
-(void)detectOrientation{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
[md changeToBigNowPlaying:YES withLayer:avPlayerLayer];
}
if(orientation == UIInterfaceOrientationLandscapeRight || orientation == UIInterfaceOrientationLandscapeLeft) {
[md changeToBigNowPlaying:NO withLayer:avPlayerLayer];
}
}
in my app I got a Home with several buttons. Each button opens a separate view. In each view, if I put the device in landscape a help view is shown. Everything works fine except that in whatever view I am, if I put the iPhone like to lay on a table (I don't know how to eplain better...) the app exites from that view and comes back to the first view, the Home.
Here's my code:
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)name:#"UIDeviceOrientationDidChangeNotification"
object:nil];
[self performSelector:#selector (ritardo) withObject:nil afterDelay:5.0f];
}
-(void)orientationChanged:(NSNotification *)object{
UIDeviceOrientation deviceOrientation = [[object object] orientation];
if (deviceOrientation == UIInterfaceOrientationPortrait)
{
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
self.view = self.portraitView;
}
else if (deviceOrientation == UIInterfaceOrientationLandscapeLeft || deviceOrientation
== UIInterfaceOrientationLandscapeRight)
{
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
self.view = self.landscapeView;
}
[UIView commitAnimations];
[self dismissModalViewControllerAnimated:NO];
}
-(void) ritardo {
ruota.image = [UIImage imageNamed:#"RuotaPerAiuto.png"];
}
- (void)viewDidUnload
{
[self setPortraitView:nil];
[self setLandscapeView:nil];
[self setRuota:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
#end
Hi hope you can help me
EDIT:
I modified the -(void)orientationChanged:(NSNotification *)object{ in this way:
-(void)orientationChanged:(NSNotification *)object{
UIDeviceOrientation deviceOrientation = [[object object] orientation];
if (deviceOrientation == UIDeviceOrientationFaceUp)// || deviceOrientation ==
UIDeviceOrientationFaceDown)
{
return;
}
if (deviceOrientation == UIInterfaceOrientationPortrait || deviceOrientation ==
UIInterfaceOrientationPortraitUpsideDown)
{
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
self.view = self.portraitView;
}
else
if (deviceOrientation == UIInterfaceOrientationLandscapeLeft || deviceOrientation ==
UIInterfaceOrientationLandscapeRight)
{
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
self.view = self.landscapeView;
}
[UIView commitAnimations];
[self dismissModalViewControllerAnimated:NO];
}
Now, if I'm in portrait and get the iPhone to faceUp position works good. But when I change position from faceUp to portrait it goes back to the home...
The problem is that UIDeviceOrientationDidChangeNotification will be fired independently from shouldAutorotateToInterfaceOrientation. And you don't handle the cases UIInterfaceOrientationPortraitUpsideDown, UIDeviceOrientationFaceUp and UIDeviceOrientationFaceDown in the method orientationChanged:. So when the device is rotated to one of these orientations, your code is equivalent to:
-(void)orientationChanged:(NSNotification *)object
{
[UIView commitAnimations];
[self dismissModalViewControllerAnimated:NO];
}
So you should remove the lines:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:)name:#"UIDeviceOrientationDidChangeNotification" object:nil];
and put you code in the method willRotateToInterfaceOrientation:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
if (UIInterfaceOrientationIsPortrait(interfaceOrientation)) {
self.view = self.portraitView;
} else {
self.view = self.landscapeView;
}
[UIView commitAnimations];
[self dismissModalViewControllerAnimated:NO];
}
Edit
If you want to keep orientationChanged, then modify it as follows:
-(void)orientationChanged:(NSNotification *)object{
UIDeviceOrientation deviceOrientation = [[object object] orientation];
if (deviceOrientation == UIInterfaceOrientationPortrait) {
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
self.view = self.portraitView;
[UIView commitAnimations];
[self dismissModalViewControllerAnimated:NO];
} else if (deviceOrientation == UIInterfaceOrientationLandscapeLeft || deviceOrientation == UIInterfaceOrientationLandscapeRight) {
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
self.view = self.landscapeView;
[UIView commitAnimations];
[self dismissModalViewControllerAnimated:NO];
}
}
I have an application in which I am changing screen orientation. But when I change orientation for the first screen and go to the next screen, the change does not persist.
Attached are images for clearer understanding.
The main problem is that when device is rotated then first screen rotates but second does not launch in the new orientation.
It will rotate only when we change orientation after the screen is launched.
How do I fix that?
The problem is that when you rotate the device then
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
Method gets called but when you go to the next screen then this method does not get called. if you rotate your device again then that method gets called.
So if you want to change next screen orientation as device current orientation, then check the device's current orientation with viewDidLoad method or ViewWillApper() method. Then according to that set your current view.
Use this buddy...
If suppose, you are adding UIImageView to your self.view as
**in .h**,
UIImageView *topView
**in .m**,
topView = [[UIImageView alloc] initWithImage:
[UIImage imageNamed:#“anyImage.png"]];
topView.userInteractionEnabled = YES;
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
topView.frame = // set your dimensions as per landscape view
}
else if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
topView.frame = // set your dimensions as per portrait view
}
[self.view addSubView : topView];
**Add this lines at end of your viewDidLoad.**
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didRotate:)
name:#"UIDeviceOrientationDidChangeNotification"
object:nil];
**And the method**
- (void)didRotate:(NSNotification *)notification
{
UIDeviceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
CGRect screenBounds = [[UIScreen mainScreen] bounds];
switch (orientation)
{
case UIInterfaceOrientationLandscapeLeft:
{
topView.frame = // set your dimensions as per landscape view
break;
}
case UIInterfaceOrientationLandscapeRight:
{
topView.frame = // set your dimensions as per landscape view
break;
}
case UIInterfaceOrientationPortraitUpsideDown:
{
topView.frame = // set your dimensions as per portrait view
break;
}
case UIInterfaceOrientationPortrait:
{
topView.frame = // set your dimensions as per portrait view
break;
}
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
Happy coding..
call this method.
-(void) viewWillAppear:(BOOL)animated{
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
[self willAnimateRotationToInterfaceOrientation:orientation duration:0];
}
-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown )
{
enter code here
set frame.........
}
else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight )
{
set frame.........
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}