Device orientation analytics - iphone

I am trying to decide if I should implement landscape mode in my application. Is there an analytics software that will tell me if users try to view my app in landscape mode? Or should I write me own methods?

You can use heatma.ps SDK to view statistics for each screen of your application. It's automatic so you don't have to implement orientation support to find out.

It's hard to tell given the shouldAutorotateToInterfaceOrientation: call is made for all orientations no matter whether the user tries to go to landscape mode, and the willRotate/didRotate callbacks are only made for supported orientations. What you could do is log the
[[UIDevice currentDevice] orientation];
on each shouldAutorotateToInterfaceOrientation. Or register for the UIDeviceOrientationDidChangeNotification notification. This returns a UIDeviceOrientation, no matter the orientation of you view controllers. Note that this is different from the UIInterfaceOrientation values which UIViewControllers use for the interfaceOrientation property.
typedef enum {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait,
UIDeviceOrientationPortraitUpsideDown,
UIDeviceOrientationLandscapeLeft,
UIDeviceOrientationLandscapeRight,
UIDeviceOrientationFaceUp,
UIDeviceOrientationFaceDown
} UIDeviceOrientation;
Although the two are related:
typedef enum {
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
} UIInterfaceOrientation;

You can use Google Analytics User Timings to measure the time interval a user spends in a specific orientation. You can read about tracking user timings for native ios apps at
https://developers.google.com/analytics/devguides/collection/ios/v2/usertimings

Related

Different Orientation for Different Views?

I'm making an iOS application that has an interface in the portrait view.
However, when displaying web content I want the view to display in a landscape format, because I want the website test to display larger initially without the user needing to zoom.
Can I tell the program so present this view only in landscape?
Thank you.
looks like you want to force the orientation to landscape mode only..
heres my solution in MyViewController.h
add this code on top of MyViewController's #interface
//force orientation on device
#interface UIDevice (PrivateOrientation)
- (void) setOrientation:(UIInterfaceOrientation)orientation;
#end
then in the implementation file (MyViewController.m)
add this code inside viewWillAppear:
//change orientation of device
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeLeft];
this will force the device orientation to landscape mode left (or right depending what you want) if you want to go back to portrait mode after leaving the viewcontroller add this code inside viewWillDisappear:
//change orientation of device
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
finally implement shouldAutorotateToInterfaceOrientation: to force the view into landscape mode left or right (or both)
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
hope this helps :3

iPad launch orientation when flat on surface

I have the following code:
-(void)viewWillAppear:(BOOL)animated {
UIDeviceOrientation orientation = [[UIDevice currentDevice] UIInterface];
if(orientation==UIDeviceOrientationLandscapeLeft || orientation==UIDeviceOrientationLandscapeRight) {
NSLog(#"Device Landscape");
} else {
NSLog(#"Device Portrait");
}
}
This works perfectly for the simulator and on the device but only if the iPad is not flat on a surface, for example if i lay the iPad on my desk and load the view it will say its portrait and so I cant detect the orientation when the view appears.
Any ideas of the best way to detect the interface orientation when the viewWillAppear is called?
Thanks
You should use [self interfaceOrientation] instead of the device orientation.
[[UIApplication sharedApplication] statusBarOrientation] also works if you are somewhere in the code that does not have access to [self interfaceOrientation]
First, do you know about the interfaceOrientation property of UIViewController? It looks like you are trying to duplicate it. If you really want to do that, simply subscribe to device orientation change notifications, check if the new orientation is valid interface orientation (the is a macro for that) and if yes, store the value to some variable (like lastSeenOrientation). Then you can rely on that value wherever you want.

Inaccurate device orientation returned by UIDeviceOrientationDidChangeNotification

I'm listening to the UIDeviceOrientationDidChangeNotification in order to adjust my UI based on the device's orientation.
The problem is that the device orientation I'm getting from the notification seems inaccurate. If I start with the phone in portrait orientation and vertical (as if taking a picture with it) the orientation I get from the notification is correct. As the tilt of the phone approaches horizontal (as in laying flat on a table top) the orientation switches to landscape. This happens much before the phone is actually flat on the table. And this is without rotating the phone towards landscape at all. Is as if it had a preference for landscape.
When using other apps, like mail, I don't see this same behavior. It seems that mail only switches orientation once it's really sure you've gone to the new orientation.
Any help greatly appreciated.
Thanks,
I found my problem.
In viewWillAppear I have:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(didChangeOrientation:) name: UIDeviceOrientationDidChangeNotification object:
[UIDevice currentDevice]];
And here is the notification handler:
- (void) didChangeOrientation: (id)object {
UIInterfaceOrientation interfaceOrientation = [[object object] orientation];
//DLog(#"val is %i", interfaceOrientation);
if (interfaceOrientation == UIDeviceOrientationLandscapeLeft || interfaceOrientation == UIDeviceOrientationLandscapeRight || interfaceOrientation == UIDeviceOrientationPortrait) {
[self orientInterface:interfaceOrientation];
}
By checking that the orientation is one of the two landscapes or the two portraits I'm ignoring the UIDeviceOrientationFaceUp and UIDeviceOrientationFaceDown orientations. That way setting the phone in one of this two orientations won't have an effect on my interface's orientation.
My problem was that I was no considering the faceUp and faceDown and was handling them both in an else statement which was assuming landscape.
If your only interest is your interface orientation (ie landscape or portrait orientation of the device), you should NOT use UIDevice:orientation (or the UIDeviceOrientation* constants if you will), but rather use the UIApplication:statusBarOrientation, which uses the UIInterfaceOrientation* constants.
I use the following code to check for landscape modus:
static inline bool isOrientationIsLandscape() {
return UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);
}
And for portrait modus:
static inline bool isOrientationIsPortrait() {
return UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]);
}
This cost me a whole morning to figure out, because there is no UIDeviceOrientationFace[Up|Down] on the simulator, only on the real device. So my app worked on the simulator all the time, but on the actual device I had some undefined behavoir during testing every now and then.
Now it works on the actual device like it does on the simulator.
HTH
The notifications are just one way to get at it, you can also read out the accelerometer yourself and implement it in exactly the way you see fit (with a delay and a certain time of non-rotation for example).
Don't know if it's a power drain to get those readouts, but if so, use the notification to know when things are moving, and then fire up the accelometer-reading.

iPhone SDK: Forcing landscape mode for a single part of an app

Yet another landscape mode question.
We've all seen the
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
Nonsense. I have not been able to get this to work on the simulator or on the device.
What I get is this:
http://i47.tinypic.com/zl9egh.png
when I really want this:
http://i45.tinypic.com/xms6cm.png
As you might be able to tell, it's flipping the phone but it's not realizing it has been flipped.
I've seen the hidden method
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
But I need this app to be on the app store, and I don't know if they will crack down on that.
Does anyone have any idea on how to get this damn thing to straighten itself out?
Ideally your view controller should implement:
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
Then the only allowed orientation for that view controller is one of the landscape orientations.
Unless you have a pretty complex view hierarchy that utilizes a tab bar controller, this should cause the view to rotate when it's pushed.
If it doesn't work you can try:
[[UIDevice currentDevice] performSelector:
#selector(setOrientation:)
withObject:(id)UIInterfaceOrientationLandscapeRight];
I have an app in the AppStore that uses this code because in my case I do have a complex hierarchy of views that keeps the one I need to be landscape only from working.
If you want to rotate a single part of the app you can use the CGAffineTransform transform property of a UIView. For an example check this thread:
How do I apply a perspective transform to a UIView?

How to control the orientation of the device in iphone / ipod?

i have to do something on rotation the device on the portrait mode but when i use the
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
//[[[UIApplication sharedApplication]keyWindow]subviews removeFromSuperview ];
// return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
return YES;
}
following code and it work fine on the simulator but when i use to install the code in the device it make the device so much sensitive that if i just a little change the position in the device it execute this code and go to the view that i m showing on the rotation of the phone
than pls anyone tell me that how can i control the sensitivity of the device i mean that i just want when user complete a 90' rotation in the position than my code should execute but it just execute if just shake the phone in the same position .
thanks for any help
Balraj verma
You probably want to buffer the orientation information; that is, only change the orientation after you have received several indications from the sensor in a row that the orientation is different from what you're currently displaying.
From my understanding of what you have written, your application is too sensitive when the device is rotated? It's difficult to understand why this is; the code you've included states that you're application is willing to accept any rotation, but you've not stated how you deal with the rotation events afterwards.
Based on the info, I can only suggest that you add a check to in your code (perhaps where the rotation event is dealt with) and obtain the orientation from the device using:
[[UIDevice currentDevice] orientation];
which will return a UIInterfaceOrientation enum stating the current orientation of the device.
UIDeviceOrientationPortrait
UIDeviceOrientationPortraitUpsideDown
UIDeviceOrientationLandscapeLeft
UIDeviceOrientationLandscapeRight
You can then use this to establish whether there's a need to change the orientation. (Note: this is iPhone OS 2.0. I believe that OS 3.0 has more including lying face up/down, etc.)
- (void) didRotate:(NSNotification *)notification
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationLandscapeRight)
{
NSLog(#"Landscape Right!");
}
}
If you find that the orientation switches too quickly you may want to buffer the information, creating several sample points that you can compare before switching to the new orientation.