I have an old app, that still lives on iTunes, written in iOS 5. I would like to update it to run on ios 6 and 7. Everything has been fine so far, and I have updated my code to use ARC. However when trying to maintain the same autorotation philosophy I keep hitting a brick wall. I have already checked relative topics within SO like:
Forcing landscape and autorotate in iOS 7,
Autorotate in iOS 6 has strange behaviour
and following a similar topic I have found this:
iOS 6 Autorotation Problems and Help
which lead me to do the following:
I have set the rootViewController within my AppDelegate like so:
self.preloadingViewController = [[PreloadingViewController alloc] initWithNibName:#"PreloadingViewController" bundle:nil];
self.window.rootViewController = self.preloadingViewController;
I have placed:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
within my AppDelegate. I have overriden shouldAutorotate and supportedInterfaceOrientations within the SuperViewController (parent in inheritance terms) of all of my app's UIViewControllers (including PreloadingViewController mentioned above):
- (BOOL)shouldAutorotate{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
and in every child UIViewController, I override
- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
with code to layout ui elements in the desirable manner for portrait and landscape orientations.
Finally my app's plist file under
Supported interface orientations
contains:
Portrait (bottom home button), Landscape (left home button), Landscape
(right home button)
all the orientations I want to support.
Still, even though supportedInterfaceOrientations and shouldAutorotate are being called for every orientation change on my rootViewController, willAnimateRotationToInterfaceOrientation is never being called. I have even overriden shouldAutomaticallyForwardRotationMethods in my SuperViewController to return YES, but to no avail.
What am I doing wrong here? Any ideas? I have even considered that the old ios5 - style xibs cause the issue but I do not think this is the case.
Thanks in advance.
In iOS 6 the way willAnimateRotationToInterfaceOrientation is called changed.
Use:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
// Something
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
// Something
}
in your rootController.
EDIT:
New main.m
#import <UIKit/UIKit.h>
#import "yourAppDelegate.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([yourAppDelegate class]));
}
}
Since my rootViewController was the only one getting its shouldAutorotate and supportedInterfaceOrientations methods called, I decided to register every other view controller to get notified of any UIDeviceOrientationDidChangeNotification.
[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
- (void)orientationChanged:(NSNotification *)notification
{
NSLog(#"Orientation changed!");
[self layoutForOrientation:[[UIDevice currentDevice] orientation]];
}
Within my layoutForOrientation: method I handled the uiview's controls orientation.
However, although I did receive UIDeviceOrientationDidChangeNotification notifications normally, my view orientation would not actually change to match the current orientation, i.e. if the new orientation was say, UIInterfaceOrientationLandscapeRight, the view orientation would remain in UIInterfaceOrientationPortrait and its children views would get rotated by 90 degrees. This did certainly not look right. After pulling a lot of hair out, I decided to abandon this route.
Instead, I have set my rootViewController to be a UINavigationController and have it push successive UIViewControllers on top of it. Since I did not want a navigation bar visible in my app I have set the navigation controller's navigationBarHidden property set to YES. This way the method willAnimateRotationToInterfaceOrientation is getting called on every UIViewController that is currently at the top of the navigationCotroller's stack of controllers, and its corresponding view and view controls rotate correctly for the desired orientations.
This works because most of my view controllers supported interface orientations match the mask: UIInterfaceOrientationMaskAllButUpsideDown, the default behaviour for iPhone. Should I needed to support different orientations, I would have to subclass the UINavigationController and override supportedInterfaceOrientations and shouldAutorotate to enable the desired orientations support for the navigation stack's top view controller, as per Apple's example project: AlternateViews.
Implement this method, return YES for what you need.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
Related
I have an iPhone application most of which is portrait-only, but with one view controller (a video player screen) that has to support both portrait and landscape (this is for iOS 8 only). To achieve this, I have set the app's plist to support portrait and both kinds of landscape, then subclassed UINavigationController; in this subclass I override
- (BOOL)shouldAutorotate {
return YES;
}
and
- (NSUInteger)supportedInterfaceOrientations {
if ([self.visibleViewController isKindOfClass:[MyVideoPlayerScreen class]]) {
return UIInterfaceOrientationMaskAllButUpsideDown;
} else {
return UIInterfaceOrientationMaskPortrait;
}
}
This mostly works as expected: the initial screens are all portrait-only, and remain in portrait even when the device is turned to landscape. The video player, when initially presented:
MyVideoPlayerScreen *newVC = [MyVideoPlayerScreen new];
[self.navigationController pushViewController:newVC animated:YES];
is also in portrait but will then rotate to landscape when the device is turned - all good so far.
The problem is that if I turn the device to landscape, the video player goes landscape as well, but then when I dismiss the video player screen via the back button, the underlying view controller (which is supposed to be portrait-only) is now also in landscape. If I rotate the device back to portrait the view controller rotates back to portrait as well, and it is then correctly locked in portrait-only from that point on.
How can I get the original view controller (which is supposed to be portrait-only) to automatically go back to portrait when the landscape view controller above it is popped?
This question has been asked a million times, but it seems that the fixes that were posted for it are all hacks that don't work in iOS 8 any more.
Update: I have found a "sort-of" fix for this that does work in iOS 8. In my UINavigationController subclass, I handle the <UINavigationControllerDelegate> protocol. I implemented this method:
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (![viewController isKindOfClass:[MyVideoPlayerScreen class]]) {
// if the current orientation is not already portrait, we need this hack in order to set the root back to portrait
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (orientation != UIInterfaceOrientationPortrait) {
// HACK: setting the root view controller to nil and back again "resets" the navigation bar to the correct orientation
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIViewController *vc = window.rootViewController;
window.rootViewController = nil;
window.rootViewController = vc;
}
}
}
This at least leaves the UI in the state I want it to be in. The problem is that when the top-level view controller is dismissed and animated off-screen, the underlying view controller is still in landscape; then it suddenly jumps to portrait. Not ideal, but better than nothing.
Update 2: I should have added that I am pushing the second view controller like so:
ViewControllerPortraitLandscape *newVC = [ViewControllerPortraitLandscape new];
[self.navigationController pushViewController:newVC animated:YES];
Update 3: OK, this is totally doable, in a way that works for iOS 6 and up. The fix even kind of makes sense, although the reason for it's working does not seem to be in the documentation anywhere. Basically, in the view controller that you need to be reset to portrait when the top-level view controller is dismissed while the device is still in landscape, you just need to add this:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Although my subclass of UINavigationController is entirely responsible for the rotation calls, breakpoints show that supportedInterfaceOrientations is called on the underlying view controller just before the top-level is dismissed, and it's called on the navigation controller after the top-level is dismissed. So I'm inferring that this call to the view controller itself is made by iOS in order to determine what orientation the underlying view controller should be in (and it does not ask the nav controller for this); if it's not explicitly overridden it will return the all-but-upside-down parameter, so iOS just leaves it where it is, in landscape.
Turns out this is an easy fix: you can drive the entire process via a subclass of UINavigationController as I posted here (i.e. not implementing any of these rotation methods in the view controllers themselves), except that for any view controller that needs to be portrait-only, you also need to implement this:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
With breakpoints, you can see that this method is called before the pushed view controller above it is dismissed; iOS presumably uses this call to determine what orientation the "revealed" view controller should be in (the same call to the navigation controller subclass is called after the top-level view controller is dismissed).
With this method implemented in the view controller, everything works as expected.
Be portrait EXCEPT when presenting a particular UIViewController subclass. This article helped a lot: ~~removed because of spam~~
set the Info.plist to support, portrait, landscape left, landscape right
implement application:supportedInterfaceOrientationsForWindow: like so:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
}
// (I specifically want landscape left for the movie viewing)
subclass UINavigationController(the windows' rootViewController) and override like so:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait; // enforces the “portrait everything” requirement
}
finally, I had to make sure the custom player view controller would "override" the supported orientation:
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
Result:
UIViewController subclass presents but when dismissing the custom view controller, the presenting view controller is Portrait.
From fantageek article: "The system intersects the view controller’s supported orientations with the app’s supported orientations (as determined by the Info.plist file or the app delegate’s application:supportedInterfaceOrientationsForWindow: method) to determine whether to rotate."
I think you should change to this and try again
-(NSUInteger)supportedInterfaceOrientations {
if ([self.visibleViewController isKindOfClass:[MyVideoPlayerScreen class]])
{
return UIInterfaceOrientationMaskLandscape;
}
else
{
return UIInterfaceOrientationMaskPortrait;
}
}
Here's how you do it.
Implement these 3 methods on both presenting and presented controller:
- (BOOL)shouldAutorotate {
return NO; //-- for presented controller use YES
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape; //-- any orientation you need
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeRight;
}
and now you can use in the presenting controller:
[self presentViewController:presentedController animated:true completion:nil];
This way, when you go back to presenting controller, it will have the correct orientation.
My case has 3 view controller:
- first view controller: portrait
- second view controller: landscape right (has navigation controller and was presented by first view controller)
- third view controller: portrait (has navigation controller and was pushed by second view controller )
And my solution had already here. Hope this helps
I have th e following code in my uiviewcontroller.m file:
-(BOOL)shouldAutoRotate
{
return YES or NO;
}
I have tried both YES and NO but my view controller still rotates? I am using iOS 7 and the other iOS solutions I found aren't working for me either.
It probably happens because your controller instantiated as child of UINavigationController in view hierarchy. The UINavigationController does not query child controllers if they want to be rotated or not.
I had the same issue; I wanted to disable autorotation, so all hierarchy of particular UINavigationController is locked in Portrait. I ended with this class:
#implementation FixedOrientationNavigationController
- (BOOL)shouldAutorotate {
return NO;
}
#end
which I put instead of UINavigationControllr class in Storyboard for hierarchies which I need to lock Portrait. Just this, I do not need to implement shouldAutorotate in each controller.
You may also check this link: Orientation Respectful UINavigationController, it tries to implement "orientation respectful" UINavigationController.
It works, but in some cases it leads to weird results, for example, when user rotate to Landscape and then go back to the controller which should only support Portrait.
You can also set the orientation by clicking on project name and then general ,here you can set the orientations you want and set
- (BOOL)shouldAutorotate {
return NO;
}
Hope you got.
In direct reference to this question:
How to stop rotation of ABPersonViewController & ABNewPersonViewController in Landscape mode in iphone
How can I prevent this screen from rotating in iOS 6 when I am not the one pushing the view controller? Scenario being I create a new contact, and the user then presses either the 'Create new contact' or 'Add to existing contact' buttons. The screen produced is the ABNewPersonViewController but because I do not have direct access to the rotation methods, I am unable to prevent it from rotating.
Screenshot:
The above image is taken from a subclass of the ABUnknownPersonViewController, in this subclass the only functionality I have implemented is to override the rotation methods as follows:
- (BOOL)shouldAutorotate
{
return NO;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
if(toInterfaceOrientation == UIInterfaceOrientationPortrait)
return YES;
return NO;
}
However, the issue is, I cannot then subclass the ABNewPersonViewController screen that is pushed when one of the buttons in the above image is pressed to override the rotation on iOS 6. Any ideas on how I can legitimately get access to these buttons OR override the rotation on the screen that is pushed to prevent it from doing so?
UPDATE 1:
I attempted to create a category on the ABNewPersonViewController and ABUnknownPersonViewController that overrode the rotation methods (not ideal, I know) and then globally imported, but this did not work. Other than this, I am completely stuck for ideas on how to override this behaviour. Any suggestions?
UPDATE 2:
Is it possible to gain a reference to the buttons in that UITableView and override the methods they call? Or is this in violation of Apple terms by accessing private APIs? Trying to investigate this approach so far and not really getting anywhere.
On iOS 6, rotation handling has changed. There are two options to prevent the rotation:
You can set your whole app to only support portrait orientation in your Info.plist.
You can override a method in your application delegate:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait;
}
As that method is called on your delegate whenever the orientation changes or a new view controller is pushed, you can even use it to temporarily disable landscape display:
// In AppDelegate.h:
#property (nonatomic) BOOL portraitOnly;
// In AppDelegate.m:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return _portraitOnly ? UIInterfaceOrientationMaskPortrait : UIInterfaceOrientationMaskAllButUpsideDown;
}
// to switch to portrait only:
((AppDelegate *)[UIApplication sharedApplication].delegate).portraitOnly = YES;
// to switch back to allowing landscape orientations as well:
((AppDelegate *)[UIApplication sharedApplication].delegate).portraitOnly = NO;
Both methods are perfectly acceptable for App Store submission, as these only use published and documented behavior.
Going off of Tammo Freese answer. I assume the view that needs to be allow landscape is lower in the view stack than your custom ABUnknownPersonViewController. If so in your ABUnknownPersonViewController subclass over add this
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
((AppDelegate *)[UIApplication sharedApplication].delegate).portraitOnly = YES;
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:(BOOL)animated];
((AppDelegate *)[UIApplication sharedApplication].delegate).portraitOnly = NO;
}
In iOS 6 what orientations view controllers are allowed to rotate to is controlled by the top-most full screen view controller, and autorotation methods are no longer called down the view controller hierarchy.
Instead of creating a subclass of the ABPersonViewController, create a subclass of UINavigationController with this code:
- (BOOL)shouldAutorotate
{
return NO;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Use this new subclass when creating the UINavigationController for the ABPersonViewController you are presenting. If the UINavigationController is not being presented modally (and is instead nested in a UITabBarController or another view controller), you will need to also put these methods in that view controller as well.
Last time I ran an iOS app I made, it must have been on for deployment target 5.0 and the associated SDK (there's a chance it could have been as early as 4.3). The deployment is now 6.1. My app only runs landscape and worked fine in landscape. But after I updated my iPad and iOS SDK and ran this app for the first time in about a year, it seems something has changed.
The buttons show up as if the iPad is in portrait mode. This is wrong, because it should be in landscape (and it used to work just fine).
What has changed in the newest updates?
My supported interface orientations in Xcode have "Landscape Right" selected only and in the Info section I have "Supported interface orientations" with just a single Item: "Landscape (right home button)".
In my main view control that opens when the app first opens, I have
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight ||
interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
and also the first line of the viewDidLoad is
self.view.frame = CGRectMake(0, 0, 1024, 768);
So why is the code drawing buttons as if it is in Portrait mode?
UPDATE
I have tried to replace the shouldAutorotateToInterfaceOrientation method with
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationLandscapeRight & UIInterfaceOrientationLandscapeLeft;
}
but it still doesn't work.
Orientation changes in iOS6.0
You should implement the following methods
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
// Set the initial preferred orientation
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
Note
If you are using TabBarController/NavigationController you should sub class those view controller to override the orientation methods in such a way that it should call your own view controller methods. This is a significant change in iOS6.
#import "UINavigationController+Orientation.h"
#implementation UINavigationController (Orientation)
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
#end
shouldAutorotateToInterfaceOrientation is deprecated in iOS 6, you should override
supportedInterfaceOrientations method of UIViewController
There is quote from doc:
In iOS 6, your app supports the interface orientations defined in your
app’s Info.plist file. A view controller can override the
supportedInterfaceOrientations method to limit the list of supported
orientations. Generally, the system calls this method only on the root
view controller of the window or a view controller presented to fill
the entire screen; child view controllers use the portion of the
window provided for them by their parent view controller and no longer
participate in directly in decisions about what rotations are
supported. The intersection of the app’s orientation mask and the view
controller’s orientation mask is used to determine which orientations
a view controller can be rotated into.
You can override the preferredInterfaceOrientationForPresentation for
a view controller that is intended to be presented full screen in a
specific orientation.
Okay, so here's the situation:
I have an app in which I only want ONE specific view in a UINavigationController to have a landscape orientation. This view is a UIImageView that I'm capturing a signature on (THAT part works awesome). So, like this:
previous view --> signature view --> next view
(portrait) (landscape) (portrait)
I can't seem to find a good way to force the device orientation to landscape on that signature screen. It'll never make sense to have a portrait orientation on the signature view because there's really not adequate room for signing in that screen width.
So, any bright ideas on how to accomplish this? I've considered possibly doing the signature view modally, thus breaking out of the navigation controller. Thoughts?
You can try to force Device to rotate to necessary orientation - but you need to handle it manually (in addition to overriding UIViewController orientation handling methods).
To rotate device you can use next methods:
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
But in it may not work in all situations...
Also available undocumented approach:
[[UIDevice currentDevice] performSelector:NSSelectorFromString(#"setOrientation:")
withObject:(__bridge id)((void*)UIInterfaceOrientationLandscapeLeft)];
Just override this UIViewController method to only return true for landscape like so and the iphone will be forced to rotate to that device orientation, since it has no other option.
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
Unfortunately, all root UIViewControllers inside of a Navigation Controller must support any of their child orientations. This means that the first view controller in your setup must support landscape, otherwise the child will only support portrait.
The best way to implement what you are looking for is to create a UIViewController that displays its content view on a rotated transform, and just default all UIViewControllers in that stack to portrait.
I think you can embed this view inside a view controller and overwrite the ShouldRotateToInterfaceOrientation method.
Good luck!
To use a View in only landscape, I have the following in the ViewController:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
This might be what your looking for.
// Rotates the view.
CGAffineTransform transform = CGAffineTransformMakeRotation(3.14159/2);
self.view.transform = transform;
// Repositions and resizes the view.
CGRect contentRect = CGRectMake(-80, 80, 480, 320);
self.view.bounds = contentRect;
from http://www.iphonedevsdk.com/forum/iphone-sdk-development/1394-landscape-uiviewcontroller-uiview-rotation.html
I have an app that has landscape only views that even starts in landscape. This was working fine in iOS 5.x but stopped working in iOS 6.x
After trying many many things, some more questionable than others, I found a solution that to me is clear and predictable.
I did several things.
-- I kept the views in landscape mode in IB.
-- I checked both landscape modes in the project settings - there a four icons there to control it
-- Orientation mgmt has changed in iOS 6.x. I had to overwrite a few methods to support changing to landscape
this method is for iOS 5.x
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations.
return (interfaceOrientation & UIInterfaceOrientationMaskLandscape);
}
these 2 methods are for iOS 6.x
- (NSUInteger)supportedInterfaceOrientations
{
NSUInteger supportedOrientations = UIInterfaceOrientationMaskLandscape;
return supportedOrientations;
}
- (BOOL)shouldAutorotate
{
return YES;
}
-- But the key was to change the logic in the AppDelegate. Original code I had there was adding a subview (controller.view) to the window. This stopped working in iOS 6.x - I changed the call to window.setRootController. That was the final step that sealed it - it would not work without making this final change
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//[self.window addSubview:viewController.view];
[self.window setRootViewController:viewController];
[self.window makeKeyAndVisible];
return YES;
}
The UINavigationController overrides the contain UIViewController orientation settings, so you have to create a custom subclass of UINavigationController with the following for 5.1:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[self topViewController] isKindOfClass:[SigCaptureViewController class]]) {
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
} else {
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
}
For 6.0 and above you need:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
if ([[self topViewController] isKindOfClass:[EXTRASigCaptureViewController class]]) {
return UIInterfaceOrientationMaskLandscape;
} else {
return UIInterfaceOrientationMaskPortrait;
}
}
What I haven't figured out is how to make the force the UINavigationController to rotate. calling [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO] causes the status bar to rotate but doesn't cause the view to rotate.