iPad OpenGL Screen Rotation Problems (Multitasking bar and Popups not Rotating) - ios

I'm building an application for the iPad using OpenGL and have issues with screen rotation. The application itself works fine and displays correctly in all four orientations, but other elements only partially respond to the device rotation.
OpenGL handles the rotation of the application using transformation matrices. That all works fine. The default images also display at the correct rotation.
The multitask bar, however, is not rotating as it should. It appears on the side that the application was opened in. So if I open the application then double tap the home button it is on the correct side, but after rotating the device it remains on the same side until the application is closed and reopened. When this bar is revealed the OpenGL application rotates to match the bar's position.
Dialogue boxes, such as the 'sign into game center' popup are also not correctly rotated. They seem to appear in the standard portrait orientation.
I'm not sure if there are any other specific details necessary to identify the problem but any suggestions are very much appreciated.

I seem to have put together a solution looking at snippets in some other threads. I think it's fixed the problem.
I have a main class which controls most of my application. It was already registered to receive device rotation notifications like this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
I added a few lines to the orientation handler function to manually set the status bar location:
- (void) updateOrientation {
if ([[UIDevice currentDevice] orientation] < 5 && [[UIDevice currentDevice] orientation]>0) {
orientation = [[UIDevice currentDevice] orientation];
[UIApplication sharedApplication].statusBarOrientation = orientation;
}
}
The conditional limits the handler to respond only to landscape and portrait orientations and not face up and face down.
If anybody has a better solution I'd still like to hear it, otherwise, hope this can help someone else.

Related

Fixed video capture orientation for RTCMTLVideoView webrtc

I have an iOS app that only supports portrait when rotating the device the video captured by the RTCMTLVideoView rotates to landscape orientation, even when the rest of the UI stays in portrait.
So far the only solution that I found is to listen for the UIDeviceOrientationDidChangeNotification notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
and disabling it
- (void)orientationChanged:(NSNotification *)notification{
NSLog(#"orientation changed");
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}
Is there any way to prevent this behaviour and keep it locked to portrait without this ugly workaround?
The problem in my case was that the video captured with the front camera was no mirrored.
I fixed the issue flipping the RTCMTLVideoView
self.myRTCMTLVideoView.transform = CGAffineTransformMakeScale(-1.0, 1.0)
The answer assumes usage of the latest stable M70 branch of WebRTC at the moment, as it's a moving target and API of its internal classes changes frequently.
Looks like RTCMTLVideoView is still work in progress and doesn't handle all scenarios appropriately. It has a rotationOverride property, but no documentation or example on how to use it. There is a similar question on Google Groups, which hasn't yet received attention, I encourage you to participate in discussion there, so WebRTC developers would know about that issue relevancy and made actions to fix it.
In the meantime, I suggest to switch to RTCEAGLVideoView which should work fine in that case.

How to lockScreen and unlockScreen remotely in iOS?

is there any API can do it?I want to lock screen and unlock it remotely in the setting time,without password,just make the screen black and can make it bright again,the case like this:
[[UIDevice currentDevice] setProximityMonitoringEnabled:YES]
when we get the phone near our ears the screen closes,and far bright again,i just want to controll the screen lock and unlock remotely.

iPad App Crashes on Orientation change

I am developing an iPad app. I allow both landscape and portrait mode. My UI is fine in portrait mode but when I change it to landscape mode, my UI gets messed up. I saw some SO posts related to this and I added following code in initWith... in my UIView.
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(abc)
name:UIDeviceOrientationDidChangeNotification
object:nil];
My UI is working fine in portrait mode after doing this. When I change it to landscape mode, my UI is fine. But after I change it back into portrait mode, my app crashes. I read some posts on SO related to app crashing an got to know about instruments. I enabled zombies and found that a message is being sent to already released object and this message is coming from NSNotificationCenter.
Is there something else that I need to handle apart from registering my device ? Also, is there any way where in I can change the implementation from UIView to UIViewController and implement the methods that UIViewController has regarding device orientation ? Please let me know the steps I need to follow in order to get this done. Thanks!
Where are you registering for the notifications? You need to remove the observer when you are about to change orientations (either in prepForSegue or willAnimateRotationToInterfaceOrientation depending on however you've got your setup) in order prevent messaging a no longer valid object. You also don't want to pile up several notifications if your registering in viewDidAppear/viewWillAppear.
Remove the observer using:
[[NSNotificationCenter defaultCenter] removeObserver:self];//removes all notifications for that object (the way I've used it before)
or if you want to be specific, do something like:
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice];//remove just that notification
The UIViewController class has several methods that deal with changes in orientation. See the docs for a discussion of those methods.
One method you should look into is viewWillLayoutSubviews. This is a common place to perform manual view layout. This is called anytime the view controller's orientation changes.
Using these methods is much more common than registering for device orientation change notifications. Based on your statements about the crash, a possible issue is that you never remove the observer that you add. For every call to addObserver there must be a corresponding call to removeObserver. Otherwise the observer is called even if it has long gone away. And this results in the crash you describe.

Detecting device rotation when UIImagePicker is presented view

I am using the UIImagePickerController class and my buttons are in the camera overlay.
I would like to adjust the orientation of my camera buttons dynamically depending on device orientation the way Apple's Camera.app does. I understand that UIImagePickerController is portrait mode only and should not be subclassed. Still, I would like to be able to trap and respond to the device rotation viewController events.
Is there any clean way to do this? The viewController which presents the UIImagePickerController no longer responds to events once the picker is presented.
There seem a few related questions on this topic but none that clarify if what I want to do is possible or not. Compounding confusion, there seems to be some differences with UIImagePickerController functionality between iOS versions. I am developing this on iOS6/iPhone4 but would like to be compatible with iOS5.
Here is a clean way to do it, tested on iPhone4s/iOS5.1 and iPhone3G/iOS6.1
I am using Apple's PhotoPicker sample and making a couple of small changes. I expect you can adapt this approach for your project. The basic idea is to use notifications to trigger a method every time we rotate. If that method is in the overlay's view controller, it can carry on manipulating the overlay while the imagePicker is showing.
In OverlayViewController.m add this into initWithNibName
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:#selector(didChangeOrientation)
name:#"UIDeviceOrientationDidChangeNotification"
object:nil];
These notifications continue to be sent while the pickerController is showing. So here, in the overlay's view controller, you can continue to play with the interface, for example:
- (void) didChangeOrientation
{
if (UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {
self.cancelButton.image =[UIImage imageNamed:#"portait_image.png"];
} else {
self.cancelButton.image =[UIImage imageNamed:#"landscape_image.png"];
}
}
you will need to kill the notification and remove the observer in viewDidUnload:
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] removeObserver:self];
Note the way this app is designed: the overlayViewController acts like a wrapper around imagePickerController. So you invoke the imagePicker through the overlayViewController:
[self presentModalViewController:self.overlayViewController.imagePickerController animated:YES];
The overlayViewController acts as the delegate for imagePickerController, and in turn has delegate methods to relay information back to the invoking view controller.
An alternative is not to use UIImagePickerController at all, but to use AVFoundation media capture instead which gives you much more fine-grained control over the picture-taking process, at the expense of (slightly) greater complexity.

Determining statusbar orientation

I am wanting to detect where the status bar is on my current view in order to determine which segue to perform. I know the preferred way to do this is to determine the device orientation, but there are two problems with this approach for me:
1.) If the device is not angled far enough away from vertical or horizontal then there is no device orientation detected and the segue doesn't happen
2.) Under certain conditions I am going to "lock" the display orientation such that even though the physical device orientation is landscape the screen is going to be locked to portrait and I will want to perform the portrait segue I have created.
The problem is that the " [UIApplication sharedApplication].statusBarOrientation = " is not returning the actual orientation of the status bar. Is there not an easy way to detect this? Otherwise I am going to have to write a bunch of messy code to keep track of this.
Have you tried: [[UIDevice currentDevice] orientation]?
Note:
Depending on the design of your app it might be necessary to call [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]. If you do that, make sure to call [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications] at some point.
If that's not sufficient for your purpose I guess you have to manually check the accelerometer. Take a look at: Handling Motion Events for more info on how that's done.

Resources