I want to get notification when a user is rotate the screen to landscape or portrait,
it is possible?
I find couple of article but i didn't found answer for this.
If you want to be notified when the device has been rotated you can either implement the shouldAutorotateToInterfaceOrientation: method in your view controller or you can register to receive the UIDeviceOrientationDidChangeNotification.
Before we start, the device orientation and the interface orientation can be different. The device may be landscape but the interface may remain portrait depending on how the app has been written. Device notifications are sent shortly before the interface orientation is changed to match the device orientation. If you don't want the interface orientation to change you should implement the shouldAutorotateToInterfaceOrientation: method in your view controller to return NO. This will stop the interface orientation being updated.
From your question it sounds like you want to receive notifications so I think you want to use the second method. You can enable UIDeviceOrientationChangeNotifications using:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
There is a corresponding:
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
You can register to receive the notifications in the normal way, using the NSNotificationCenter and registering to receive the UIDeviceOrientationDidChangeNotification:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
Finally, you would implement the method to be called when the notification is received as follows:
- (void)orientationChanged:(NSNotication *)notification {
UIDeviceOrientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationPortrait ||
orientation == UIDeviceOrientationPortraitUpsideDown) {
// Portrait
} else {
// Landscape
}
}
As you can see, the orientation can be accessed using the orientation instance method of UIDevice.
You need to add local notification in the landscape orientation in shouldAutorotateToInterfaceOrientation method
try like this:
if(interfaceOrientation == UIInterfaceOrientationLandscapeRight || UIInterfaceOrientationLandscapeLeft)
{
here schedule your local notification
}
Related
In iOS, how to move UI elements (buttons and labels) when a device rotate to landscape mode from portrait mode?
There are so many ways.
In my case, I'm using notification
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(rotated:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
In rotated method
-(void) rotated: (NSNotification*) notification
{
orientation = [[UIDevice currentDevice] orientation];
if(UIDeviceOrientationPortraitUpsideDown==orientation)
// UI relocation
else if(UIDeviceOrientationPortrait==orientation)
// UI relocation
else if(UIDeviceOrientationLandscapeRight==orientation)
// UI relocation
else if(UIDeviceOrientationLandscapeLeft==orientation)
// UI relocation
}
I am installing AdMob's ad, and there is a GADBannerView.
After installing, a banner show, and if you click on it, a page will slide out coving the whole screen, and displaying advertising contents in it.
The question is, some advertising contents, such as video, had to be played landscape. However, I don't want other part of my application to rotate, as the app is not designed to be viewed in landscape.
So, how can I implement something which can achieve such function?
Try to use Notification for this. a notification calls a selector every time when ur device orientation is changed.
write this in your viewDidLoad:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(setScreenWithDeviceOrientation:) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
and then define the selector as follows:
-(void)setScreenWithDeviceOrientation:(NSNotification *)notification
{
UIDeviceOrientation orientation=[[UIDevice currentDevice] orientation];
if(orientation==UIInterfaceOrientationPortrait) //Portrait orientation
{
// setView frame for portrait mode
}
else if(orientation==UIInterfaceOrientationPortraitUpsideDown) // PortraitUpsideDown
{
// setView frame for upside down portrait mode
}
else if(orientation==UIInterfaceOrientationLandscapeLeft)
{
// setView frame for Landscape Left mode
}
else if(orientation==UIInterfaceOrientationLandscapeRight) //landscape Right
{
// setView frame for Landscape Right mode
}
else
{
NSLog(#"No Orientation");
}
}
this method fired everytime when ur device changes orientation. Based on the current orientation you should adjust your view.
I hope this will help you.
Are you working with iOS 6? You should be able to just restrict what orientations your view controller handles in this case. For example, in your view controller that handles your GADBannerView, you can just put:
// Tell the system what we support
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
// Tell the system It should autorotate
- (BOOL) shouldAutorotate {
return NO;
}
// Tell the system which initial orientation we want to have
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
And that should make it so that your viewcontroller only supports portrait.
Have you looked at this question and answer? This explains how a single view can work in a certain orientation that is not supported by the rest of the application:
AutoRotate ONLY MpMoviePlayerControler iOS 6
I'm trying to hide an image in a view controller when the device is rotated. I'm posting a notification in PlayerViewController and am listening for it in the app delegate, which is responsible for the bannerView:
- (void)orientationChanged:(NSNotification *)notification {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if ((orientation == UIDeviceOrientationLandscapeLeft) ||
(orientation == UIDeviceOrientationLandscapeRight)) {
bannerView.hidden = ([[self.navigationController visibleViewController] isKindOfClass:[PlayerViewController class]]) ? YES : NO;
} else {
bannerView.hidden = NO;
}
}
The PlayerViewController sends a notification and the app delegate hides the bannerView. However, when the device is laid flat on a table, the image shows. Works fine when the device is held vertically but horizontally the image appears... odd.
Here is the code to send the notification:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
... hide other stuff in this view controller
}
Any ideas why this odd behavior is occurring?
Just one tidbit more information. In the simulator the image shows when the device is in upside-down orientation, even though I have:
- (BOOL)shouldAutorotateToInterfaceOrientation (UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIDeviceOrientationPortrait) {
return YES;
} else {
return NO;
}
}
Your error might be happening because of when you're posting the notification.
willAnimateRotationToInterfaceOrientation is called before the orientation change takes place (hence the "will" in the method name). So if we're going from portrait to landscape, the current orientation may still be reported as portrait (it may not, it depends).
Now, the willAnimate... call returns the toInterfaceOrientation - the orientation that is going to happen.
You trigger your notification when you receive the willAnimate... call, and inside that notification call [[UIDevice currentDevice]orientation]: which will return portrait. Instead of requesting the orientation in your notification method you should instead pass the orientation provided in the willAnimate call.
If that wasn't clear, the one sentence summary: willAnimateRotationToInterfaceOrientation is called before the rotation changes.
When user tap on the UIView (which is fullscreen) my app needs to detect orientation and do some stuff. But there is one tiny problem.
If I start application in landscape mode and user tap background 'interfaceOrientation' variable is '0' and I don't know how to rearrange view elements. If I rotate simulator once everything is fine but if not 'interfaceOrientation' is '0'. What to do here?
UIInterfaceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
...
}
else if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
...
}
else if(interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
...
}
I'm not sure how well that is solvable. UIDeviceOrientationUnknown is 0. This means, especially for the iPad which hasn't got a gyroscope, that the orientation at this time is simply not know. Imagine your iPad laying on a table, flat and the user is starting your application: there isn't any means to define that your application is actually running in landscape or portrait, unless you tilt the device accordingly. Hence.. the orientation at startup is always 0 (unknown).
You are casting a UIDeviceOrientation type to a UIInterfaceOrientation type. Device orientations have several different values beyond those of an interface orientation.
Try using:
UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
switch (deviceOrientation) {
default:
case UIDeviceOrientationPortrait:
case UIInterfaceOrientationPortraitUpsideDown:
case UIDeviceOrientationUnknown:
//...
break;
case UIDeviceOrientationLandscapeLeft:
//...
break;
case UIDeviceOrientationLandscapeRight:
//...
break;
}
Edit: If the device orientation is unknown you should just set up your regular portrait view.
You should be able to access [UIApplication sharedApplication].statusBarOrientation if you can't access self.interfaceOrientation from your view controller.
Also, sometimes calling self.interfaceOrientation in viewDidLoad is risky because the view will load before it is aware of its orientation, so it will perform the rotation afterwards. In that case try finding it in viewWillAppear.
Or just override willRotateToInterfaceOrientation:duration and pass that information to the UIView that needs it. Note: that won't get called if you have a xib set to that orientation.
Anyone know how to do this?
I thought this:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
}
- (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
}
- (void)didAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
}
- (void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation duration:(NSTimeInterval)duration {
}
may prevent the device from rotation (overriding all rotate methods of my UIViewController and not calling the superclass) but I fear it's not the UIViewController that actually performs the rotation.
My UIViewController is in a UINavigationController.
Anyone have any ideas?
Cheers,
Nick.
You can register for the notification UIDeviceOrientationDidChangeNotification (from UIDevice.h), and then when you care about orientation changes call this method:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
When you no longer care about orientation changes, call this method:
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
The notification will be sent when applicable, and you can check [UIDevice currentDevice].orientation to find out what the current orientation is.
On a side note shouldAutoRotateToInterfaceOrientation used to be called on the time for rotation in 2.x, but in 3.0 it's much less consistent. The notification mentioned in the other post is the way to go for reliable indication of rotation.
You're returning YES from shouldAutorotateToInterfaceOrientation:, which I suspect you didn't mean to do. That's the only method you need to implement to prevent the device from rotating.
As for getting the current orientation of the device, you can use [[UIDevice currentDevice] orientation].