Hopefully somebody can point out what I'm doing wrong with my Splash screen here. The problem is that the screen is displaying in portrait mode, not landscape...
- (void)showSplash
{
UIView *modelView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024 , 748)];
UIViewController *modalViewController = [[UIViewController alloc] init];
[modelView setBackgroundColor:[[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"Splash.png"]]];
modalViewController.view = modelView;
[self presentModalViewController:modalViewController animated:NO];
[self performSelector:#selector(hideSplash) withObject:nil afterDelay:5.0];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
Thanks in advance for the help.
Looks like you are writing app for iPad. If so, you have to support both landscape as well as portrait orientation otherwise Apple will reject it. I would suggest that you should use two different images. Image specifications are as follows:
Default-Landscape.png (1004 * 768)
Default-Portrait.png (748*1024)
(I am assuming that you are showing status bar if not add 20 pixels to height of an image)
That's it, create these images and add it to your project. And you are good to go. No Need to write any additional piece of code too..
And ya make it
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
You shouldn't rely on a function in your code to display the splash screen. Just define them as the previous answer from Sumit Lonkar explains.
If you do it in code, I believe at the start of the application the orientation is always considered as portrait, then the transition to the actual orientation is triggered. This explains why your code displays first as portrait and most likely there is nothing else in the code to handle rotation. Besides, the purpose of the splash screen is to display something while the app is loading, so if you put it in code you lose the purpose.
By doing it the Apple way you leave it to another Apple process that runs before looking at your code and it will work.
Regarding the orientation supported I have on my iPad some apps that support only landscape (TapZoo for example) so it should be ok with Apple.
Related
I am updating a 5-year-old app (originally written for iOS 3!). I have made decent inroads in using autolayout and addressing deprecation warnings. But the old technique used for presenting a different view controller when the device is rotated no longer works reliably.
- (void)orientationChanged:(NSNotification *)notification {
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (deviceOrientation == UIInterfaceOrientationLandscapeRight && !showingOtherVC) {
// switch to other VC
othervc.modalPresentationStyle = UIModalPresentationOverFullScreen;
[self presentViewController:othervc animated:YES completion:nil];
[self resignFirstResponder];
}
The other view controller does appear, but it's laid out sideways, for a portrait screen, not landscape, even though the device is in a landscape orientation.
How can I update this in a reasonably easy way (i.e., not a rewrite in Swift, not restructuring the app with storyboards — which Xcode doesn't seem to facilitate via copy/paste)? And, for the benefit of others who may happen on this question, what would be the more correct way to achieve this result (new VC on orientation change) if I were writing this from scratch?
Thank you.
This was a really stupid error, but in case someone else makes it and ends up here, this was the problem.
Instead of correctly returning the mask constant:
-(UIInterfaceOrientationMask)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskLandscapeRight);
}
I was returning this other constant that autocomplete gave me:
-(UIInterfaceOrientationMask)supportedInterfaceOrientations {
return (UIInterfaceOrientationLandscapeRight);
}
Can I use interface builder to my fields different positions in landscape mode and portrait mode ? (Completely different, so I can't just use the layout properties) ?
Or is the code the only way to go ?
thanks
You can use willRotateToInterfaceOrientation method. When you change device orientation it will call..
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
-(void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
{
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
{
[label setFrame:CGRectMake(20, 52, 728, 617)];
}
else
{
[label setFrame:CGRectMake(20, 52, 728, 617)];
}
}
i would say go for the code if the fields shared by portrait and landscape mode are same. In case of having different objects in each mode wont be a good idea.
You can keep two UIViews in interface builder, and when user rotate device, you can hide one and show another based on orientation. Can you please try the following lines of code?
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if(([self.navigationController.visibleViewController interfaceOrientation] == UIDeviceOrientationLandscapeLeft) || ([self.navigationController.visibleViewController interfaceOrientation] == UIDeviceOrientationLandscapeRight)){
self.viewLandscape.hidden = NO;
self.viewPortrait.hidden = YES;
}
else {
self.viewLandscape.hidden = YES;
self.viewPortrait.hidden = NO;
}
}
Here are the approaches that you can use. Best approach is on the top
1. It's better to use auto layout for adjusting your views.
2. Auto layout + code
3. Code only.
4. You can make two views for your xib one for landscape and one for portrait. And show and hide as per the orientation. But in this you need to sync all your portrait views with landscape views (properties like text) and vice versa. This is easy to maintain but you have to take extra headache for syncing the properties of each view.
I would like to be able to rotate my splash screen on my ipad to landscape right and left.
i have enabled landscape right and left orientation in my .plist file. i've added 4 files for the LandscapeRight and LandscapeLeft:
Default-LandscapeRight#2x~ipad.png
Default-LandscapeLeft#2x~ipad.png
Default-LandscapeRight~ipad.png
Default-LandscapeLeft~ipad.png
although this shouldn't matter, in my rootviewcontroller i've got:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );
}
The splash screen loads, but it doesn't rotate.
what am i doing wrong?
As I Know Device does not recognise the Orientation in the duration of Splash Image.These SPlash images Default-LandscapeRight#2x~ipad.png
Default-LandscapeLeft#2x~ipad.png
Default-LandscapeRight~ipad.png recognise when app going to launch device then device takes Appropriate Splash Image.
Default-LandscapeLeft~ipad.png.
You can do the Alternate solution if you interested.and this is just my concept nothing more
1 create the UIIMageView for this Purpose and Add it as SUbview to Window.
2 Set iamge to that UIIMageView.
3 Set Sleep method for 3-4 seconds. like sleep(4).
4 As call goes to RootViewController manage the Orientation of Image.
like below method
this is the Method suppose you have defind In The AppDelegate class will manage the Image Orientation.
-(void)checkOrientationforSplash:(UIInterfaceOrientation)interfaceOrentaion
{
if (splashImageView.hidden==FALSE) {
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
if (interfaceOrentaion==UIInterfaceOrientationPortrait|| interfaceOrentaion==UIInterfaceOrientationPortraitUpsideDown) {
UIImage *image=[UIImage imageNamed:#"Default-Portrait.png"];
splashImageView.frame=CGRectMake(0.0, 0.0, image.size.width, image.size.height);
[splashImageView setImage:image];
}
else {
UIImage *image=[UIImage imageNamed:#"Default-Landscape.png"];
splashImageView.frame=CGRectMake(0.0, 20.0, image.size.width, image.size.height);
[splashImageView setImage:image];
}
}
}
5 You can Manage That Image Form in the Mid of App Instaltion, RoortViewController.
6 Remove That Splash Image At Specific Point.
-(void)removeSplash
{
[splashImageView setHidden:YES];
}
I hope it'll help you.
I have an iPad app that I would like to work in the sideways orientation instead of just portrait. I have programatically placed images, labels, and buttons into my view and used CGRectMake (x,x,x,x) to tell them where to go on the view into the center. When the app rotates horizontally, I need my labels and buttons to shift up (since they can't go down as far when in landscape mode), but stay in the center. Here is some code I've been playing with:
if((self.interfaceOrientation == UIDeviceOrientationLandscapeLeft) || (self.interfaceOrientation == UIDeviceOrientationLandscapeRight))
{
lblDate = [[UILabel alloc] initWithFrame:CGRectMake(384-(fieldWidth/2)-30,controlTop+45,120,40)]; //these dimensions aren't correct, though they don't matter here
lblDate.text = #"Date:";
lblDate.backgroundColor = [UIColor clearColor];
[contentView addSubview:lblDate];
} else {
//the orientation must be portrait or portrait upside down, so put duplicate the above code and change the pixel dimensions
}
Thanks for your help!
Take a look at this: iphone/ipad orientation handling
You just specify each control location depending on the rotation.
I know this might be a bit of an old question now looking to the date, but I just very recently faced the same problem. You could stumble upon many suggestions such as transforming main view's subviews or it's layers. Non of this worked for me.
Actually the solitary solution I've found is that since you want your UI controls to be located dynamically then don't deploy them mainly in the interface builder. The interface builder can be helpful knowing the desired locations for dynamic controls in both portrait and landscape orientations. i.e make two separate test views in the interface builder, one portrait and the other landscape, align your controls as you wish and right down X, Y, Width and Height data just to use with CGRectMake for each control.
As soon as you write down all needed positioning data from the interface builder get rid of those already drawn controls and outlets/actions links. They will be of no need now.
Of course don't forget to implement UIViewController's willRotateToInterfaceOrientation to set control's frame with each orientation change.
#interface
//Declare your UI control as a property of class.
#property (strong, nonatomic) UITableView *myTable;
#end
#implementation
// Synthesise it
#synthesize myTable
- (void)viewDidLoad
{
[super viewDidLoad];
// Check to init for current orientation, don't use [UIDevice currentDevice].orientation
if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft || self.interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
myTable = [[UITableView alloc] initWithFrame:CGRectMake(20, 20, 228, 312)];
}
else if (self.interfaceOrientation == UIInterfaceOrientationPortrait)
{
myTable = [[UITableView alloc] initWithFrame:CGRectMake(78, 801, 307, 183)];
}
}
myTable.delegate = self;
myTable.dataSource = self;
[self.view addSubview:myTable];
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight || toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
// Show landscape
myTable.frame = CGRectMake(20, 20, 228, 312);
}
else
{
// Show portrait
myTable.frame = CGRectMake(78, 801, 307, 183);
}
}
I'd like to have a nice start of my app by fading from the splash screen (UILaunchImageFile) into the main screen. Easy thing, I thought, just show an UIImageView with the splash screen as the very first view and then make a transition animation.
The problem is, since this is an iPad app with all four orientations supported, and splash screens for all these orientations, I would need to query which splash screen was used. I could query the current device rotation and select the image accordingly, but I wonder whether there's a better way.
So, can I query somehow which launch image was used during app start or do I need to ask for the device's current UI orientation and chose the file accordingly ?
No, you can't do this automagically. Querying the device rotation and selecting an image based on that is perfectly fine.
You really only need Portrait or Landscape in this situation though, assuming you are rotating your view properly.
As already stated by Joshua you cannot, as far as I am aware.
In case this might help someone else, if you are using asset catelogs the following code should provide the correct launch image for the current interface orientation.
NSString *suffix = nil;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
suffix = [[UIScreen mainScreen] bounds].size.height >= 568.0f ? #"-568h#2x" : #"#2x";
}
else {
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
suffix = UIInterfaceOrientationIsPortrait(orientation) ? #"-Portrait" : #"-Landscape";
suffix = [UIScreen mainScreen].scale == 2.0 ? [suffix stringByAppendingString:#"#2x~ipad"] : [suffix stringByAppendingString:#"~ipad"];
}
NSString *launchImageName = [NSString stringWithFormat:#"LaunchImage-700%#.png",suffix];