I'm using the open source CoverFlow replacement from here: http://fajkowski.com/blog/2009/08/02/openflow-a-coverflow-api-replacement-for-the-iphone/
When I detect that a certain view has gone from portrait to landscape mode, I instantiate an AFCoverFlowView and push it onto the navigation stack.
If I do so in response to
(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
The cover flow view comes up as though the phone were still in portrait mode.
If I push the view in response to
(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
it works perfectly - the view comes up in landscape mode with the phone in landscape mode
Unfortunately, the device doesn't reliable get willRotateToInterfaceOrientation messages. I have tried making sure that
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
is in loadView but that doesn't help with the notificiations.
So, my questions are:
Is there a way to reliably get willRotateToInterfactOrientation?
if not
How do I instruct AFCoverFlowView to come up in landscape mode (if the device is already in landscape mode)
I did a transformation on the flowView from the controller class like this:
CGAffineTransform transform = self.view.transform;
transform = CGAffineTransformRotate(transform, (M_PI / 2.0));
self.view.transform = transform;
Which worked well enough for my purposes.
Related
I want to play a YouTube Video in a UIWebView in fullscreen (Landscape mode)
But all my other views to be only in Portrait mode. How is it possible that only the YouTube video is in landscape mode?
Do I have to enable the landscape mode in the app targets summary?
Thanks for help! :-)
If your app is using multiple orientations then you need to define them in the Project Target summary. e.g Portrait, Landscape left & Landscape right.
If you are having your device working for iOS5, use the following method(deprecated in iOS6) for rotating to particular orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
If you are having your device working on iOS6. you should use the following methods.
– shouldAutorotate – supportedInterfaceOrientations & – preferredInterfaceOrientationForPresentation
If your app supporting both versions then you could keep the both methods and check if your view controller is responding to the particular method by
if ([self respondsToSelector:#selector(methodToCheck)])
myTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
CGAffineTransform rotate = CGAffineTransformMakeRotation(1.57079633);
[myTableView setTransform:rotate];
self.view = myTableView;
This will also work*
make sure here i have done in tableview
Hi in my application i would like to know the statusbarorientation value. For that i am using [UIApplication sharedApplication].statusBarOrientation method. Actually this method have to return 4 for landscape and 2 for potrait mode. But this method returning the values in opposite way. Means for landscape 2 and for potrait 4. Please let me know how to fix this issue.In supportedInterfaceOrientations method i am using return UIInterfaceOrientationMaskAll;
Please help me in resolving this issue.
It probably happens because the UIDeviceOrientationLandscapeRight is assigned to UIInterfaceOrientationLandscapeLeft and UIDeviceOrientationLandscapeLeft is assigned to UIInterfaceOrientationLandscapeRight.
The reason for this is that rotating the device requires rotating the content in the opposite direction.
Starting in iOS 8, you should use the UITraitCollection and UITraitEnvironment APIs, and size class properties as used in those APIs, rather than using UIInterfaceOrientation constants or otherwise writing your app in terms of interface orientation.
Anyway, taking the orientation in this way worked for me.
var orientation = UIApplication.SharedApplication.StatusBarOrientation;
switch (orientation)
{
case UIInterfaceOrientation.PortraitUpsideDown:
// The device is in portrait mode but upside down, with the device held upright and the home button at the top.
case UIInterfaceOrientation.Portrait:
// The device is in portrait mode, with the device held upright and the home button on the bottom.
case UIInterfaceOrientation.LandscapeLeft:
// The device is in landscape mode, with the device held upright and the home button on the left side.
case UIInterfaceOrientation.LandscapeRight:
// The device is in landscape mode, with the device held upright and the home button on the right side.
case UIInterfaceOrientation.Unknown
// The orientation of the device cannot be determined.
}
Consider also that
If your app has rotatable window content, however, you should not
arbitrarily set status-bar orientation using this method. The
status-bar orientation set by this method does not change if the
device changes orientation.
How can I retrieve a rotation specific applicationFrame/screen bounds? The "applicationFrame" method always returns 768x1024 on the iPad, no matter whether the device is in landscape or portrait mode. I am looking for a method that would return me 1024x768 if the device is in landscape and 768x1024 if its in portrait.
I am sure there is something like this out there but I just can't find it. In case it really doesn't exist, how do make your iPad apps landscape and portrait compatible?
[UIDevice currentDevice].orientation
Will return one of
typedef enum {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait,
UIDeviceOrientationPortraitUpsideDown,
UIDeviceOrientationLandscapeLeft,
UIDeviceOrientationLandscapeRight,
UIDeviceOrientationFaceUp,
UIDeviceOrientationFaceDown
} UIDeviceOrientation;
From there, you can deduce what the current frame should be.
Turns out applicationFrame works fine, but only if the autorotation is properly implemented! In my case the controller of the view that was added as subview to the UIWindow was released too early, which seems to cause applicationFrame to break along with the autorotation mechanism. I think this is because the responder chain can no longer function properly, yet I did not verify this.
Hi I have an app and I have two *.pngs for default splash screen:
Default-Landscape.png
Default-Portrait.png
What I want is to animate this default splash screen away when my app is loaded and ready to go.
To achieve this I would normally present an UIImageView with either default-landscape or default-portrait (depending on the device orientation), keep it on screen for a certain time and then animate it away.
My problem is that if I call [[UIDevice currentDevice] orientation] in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
The answer is always that the device is in portrait orientation even if I clearly have it in landscape. I tried this in simulator and on the device as well and the behaviour is the same.
Does anyone know a fix for this or maybe some other approach?
Thanks!
I had troubles with this and I solved it by making one image 1024x1024 and setting the contentMode of the UIImageView to UIViewContentModeTop, then using left and right margin autoresizing. So long as your portrait and landscape default images are the same layout then this will work fine.
Just to clarify here's what I used:
bgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:SplashImage]];
bgView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
bgView.contentMode = UIViewContentModeTop;
To get around this problem I installed the splash image view inside of a view controller that allowed both orientations. Even though the device reported the wrong orientation at startup, the view controller seems to get the right one.
You can use UIApplication statusBarOrientation as follows:
if ( UIDeviceOrientationIsLandscape( [[UIApplication sharedApplication] statusBarOrientation] ))
{
// landscape code
}
else
{
// portrait code
}
Maybe you could show a blank view with black background at start time and place [[UIDevice currentDevice] orientation] into this view's viewDidAppear and start your splash screen from there?
Another solution would be to read the accelerometer data and determine the orientation yourself.
To know at start what is the orientation (UIDevice orientation don't work until user have rotate the device) intercept shouldAutorotateToInterfaceOrientation of your View Controller, it is called at start, and you know your device orientation.
There are certainly times when you want to transition from the loading image to something else before the user gets control of your app. Unless your app is really simple, going from loading image to landing page probably won't be sufficient without making the app experience really suck. If you ever develop a large app, you'll definitely want to do that to show progress during setup, loading xibs, etc. If an app takes several seconds to prepare with no feedback, users will hate it. IMO, there's nothing wrong with a nice transition effect either. Almost nobody uses loading screens the way Apple suggests to. I don't know which apps you looked at that showed the "empty UI" type loading screens they suggest. Heck, even Apple doesn't do that except in their sample code and none of my clients would find that acceptable. It's a lame design.
Only the first view added to the window is rotated by the OS. So if you want your splash screen to automatically rotate AND your main view is rotatable then just add it as a child of that view.
Here is my code for fading out the appropriate splash screen image:
// Determine which launch image file
NSString * launchImageName = #"Default.png";
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
if (UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {
launchImageName = #"Default-Portrait.png";
} else {
launchImageName = #"Default-Landscape.png";
}
}
// Create a fade out effect
UIImageView* whiteoutView = [[[UIImageView alloc] initWithFrame:self.window.frame] autorelease];
whiteoutView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
whiteoutView.autoresizesSubviews = YES;
whiteoutView.image = [UIImage imageNamed:launchImageName];
[[[self.window subviews] objectAtIndex:0] addSubview:whiteoutView];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
whiteoutView.alpha = 0.0;
[UIView commitAnimations];
Note: You'll have to update it to support hi-res screens.
It sounds like you're not using the launch image the way Apple recommends in the iOS HIG. It specifically calls out that you should not use it as a splash screen, but rather as a skeleton version of your actual UI. The net effect is that your app appears to be ready just that much faster.
The suggestions that you could draw a splash screen yourself after the app has launching in viewDidAppear or similar also are missing the basic purpose of a launch image. It's not a splash screen. If your app is ready, let the user interact with it, don't waste their time drawing a splash screen.
From my five minute survey of Apple apps and third-party apps, everyone showed a portrait launch image, loaded the portrait version of the UI, and then rotated to landscape. It's been a while since programming on iOS, but I think this mirrors the order of the method calls -- first your app gets launched, then it is told to rotate to a particular orientation.
It might be a nice enhancement request to file with Apple though :)
Facing one issue with launching application in landscape orientation for IPad.
I have developed IPhone application which later I ported to IPad.
I have made setting regarding orientation in info.plist
[ UISupportedInterfaceOrientations~ipad ] to support all orientation UIInterfaceOrientationPortrait , UIInterfaceOrientationPortraitUpsideDown , UIInterfaceOrientationLandscapeLeft , UIInterfaceOrientationLandscapeRight.
but when I start IPad application in the landscape mode, it always start in the potrait mode.
Along this
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{ return YES; }
help me, if I am missing something with this..
Thanks,
Sagar
here's something I also discovered: setting the initial interface orientation in your info.plist is being ignored if you have Supported interface orientations set up with another orientation in the first slot! Put your initial orientation there as well - and the simulator will launch correctly, as will the app. this drove me nuts for a long time!
Put UISupportedInterfaceOrientations into your -Info.plist, with a setting for each orientation you support. This is used to see which orientation the app can start in. From there onwards it will ask your view controllers.
Sagar - I had the same issue but was able to resolve it.
Like yours, my app started as an iPhone app which I "upgraded" to a Universal app using the XCode wizard. I noticed that when running on the actual iPad, starting in landscape, the app would start in Portrait, then maybe rotate to Landscape. On the simulator, starting in landscape, the app would start in Landscape, then the simulator would rotate to Portrait.
On the iPad, my app is a split-view app with TabBarControllers on left and right. Each tab is a view controller that returns YES to shouldAutoRotateToInterfaceOrientation.
I noticed that a brand-new wizard-generated, simple-case with a splitviewcontroller, Universal app didn't have this problem.
The difference I found between my app and the simple-case was that I wasn't adding my splitview-controller's view to the app window in applicationDidFinishLaunchingWithOptions. Instead I was showing a "loading" view at this stage, then later when an initialization thread completed I'd add my splitviewcontroller's view (and hide the "loading" view).
When I added my splitviewcontroller's view to the app window during the call to applicationDidFinishLaunchingWithOptions everything started working fine.
There must be some magic that happens on return from applicationDidFinishLaunchingWithOptions???
Is your app similar to mine in that it isn't adding the main view controller's view to the window during applicationDidFinishLaunchingWithOptions?
As pointed out in a number of posts, you must set up the info.plist with both the supported and the initial interface orientations. However, the bigger issue is when does the initial orientation become effective? The answer is NOT when your view controller receives the "viewDidLoad" message. I found that on the iPad-1, running iOS 5.0, the requested initial orientation becomes effective only after several "shouldAutorotateToInterfaceOrientation"
messages are received.(This message passes the UIInterfaceOrientation parameter to the receiver.) Furthermore, even if the orientation says it is in Landscape mode, it may not be! The only way I found to be sure that the view is in Landscape mode is to test that the view height is less than the view width.
The strategy that worked for me was to lay out the subViews I wanted when the "viewDidLoad" message was received but to delay actually adding those subViews to the view until the controller received a valid "shouldAutorotate.." message with the orientation set to Landscape mode. The code looks something like:
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
// N.B. Even when the interface orientation indicates landscape mode
// this may not really be true. So we insure this is so by testing
// that the height of the view is less than the width
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
CGRect viewBounds = [[self view] bounds];
if ( viewBounds.size.height < viewBounds.size.width )
[self addMySubViews];
return YES;
}
else
return NO;
}
Apple has just released iOS 5.1, so this behavior may have changed. But I expect the code that is here should still work.