I have done what this question said here: Landscape Mode ONLY for iPhone or iPad
but the view.frame.size.height is still 1024, which is the height when the device is in portrait, surely when the interface rotates the width and height switch values?
(say you wanted to split the screen into 3 views, for an app that is both landscape and portrait, and you did view.frame.size.width / 3 , in landscape that wouldn't be correct as the width value wouldn't actually be the width)
I'm sure on the iPhone the width and height switch, so why not on the iPad?
This has struck me again I 'm not working with a nib either, could someone please give an acceptable answer? (ie one that doesn't involve manually switch the width and height)
Once the bounty has been awarded to an answer, I will then start another bounty for 250 and award it to the same person.
You haven't specified which "view" you're querying. Assuming this is the top level subview of the window:
You should query the view's bounds not its frame. frame is in the coordinate in which the view is defined (the outside world) hence may remain constant as you rotate. bounds is the coordinate used "inside" the view and for its subviews. This does change when you rotate.
+ (int) currentWidth
{
UIScreen *screen = [UIScreen mainScreen];
int width = screen.currentMode.size.width;
int height = screen.currentMode.size.height;
return (UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]))? MAX (width, height) : MIN (width, height);
}
I spent a while trying to work out the simplest solution to a frustrating problem, and this was the best I could come up with. Hope it can help.
Related
I'm making an iPhone app, and I'm using storyboard for the majority of the UI. I'm using xCode 4.6 for iOS 6.
Is there a way to make the app work for both iphone4 size and iphone5 sizes?
When I run the app on the iPhone 4 simulator it doesn't look like it's supposed to - the UI elements don't look like they do on the storyboard (which I'm assuming uses the iPhone5 size).
Let me know if you need more info.
You can dynamically access the height of the view and the device, and then make adjustments based on those values. Alternatively, you could use iOS 6's constraints to set a margin between the bottom of the device or between other elements.
To achieve the former, just access the height property of the view:
CGFloat height = [[self view] frame].size.height;
You can also get the height of the device's screen like so:
CGFloat deviceHeight = [[UIScreen mainScreen] bounds].size.height;
deviceHeight -= 20; // remove the tab bar
deviceHeight -= 44; // remove height for a navigation bar?
Now imagine adjust your view's origin based on this value. You can make it hug the bottom of the device, no matter which one you're on.
[aView setFrame:CGRectMake(10, deviceHeight - 10 - 100, 300, 100)];
If you're unable to adjust the layout of the elements, consider using a scroll view as well. Just set the frame using the techniques above, and then set the content size. On smaller devices, you'll be able to scroll to see more content whereas on larger devices, it will all be right there.
I'm updating an older project to support the iPhone/iPod 5's 4 inch screen. I've added the Default-568h#2x.png to my project, and almost everything seems fine, except:
the Game Center overlay (view controller) is cut off at the bottom.
Tweet sheet popups aren't full width.
Touch input isn't being received on the right/bottom side of the screen.
Seems like my window isn't the correct length.
(I'm going to propose a solution, but I'd like some feedback as to whether or not this is a safe (or "correct") solution.)
I've manually edited my MainWindow.xib file, changing the NSFrameSize from {320, 480} to {320, 568}, which has solved the apparent problem.
This doesn't seem to be causing problems on older/smaller screens, but I'm wondering if this is the best across-the-board solution...
shouldn't you get the current screen size as in the height using following and then use it
instead of changing it manually
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
I'm currently using [[UIScreen mainScreen] bounds].size.width and height to get the screen width and height for getting a new image (that fills the screen) from a server. My problem is it appears that the bounds doesn't change on orientation changes. So if I rotate the device then it still gives me portrait width/heights even though the device is now in landscape. I'd like to not hardcode a screen width/height based on the current orientation. Is there a way that I can check the screen width and height that will correctly reflect orientation changes?
You can get the width and height by
int h = self.view.frame.size.height;
int w = self.view.frame.size.width;
Best way to do this is probably:
CGSize appSize = [UIApplication sharedApplication].keyWindow.rootViewController.view.bounds.size;
and also use appSize.height for height and appSize.width for width
This returns the orientation adjusted size of the topmost view which always fills the full screen, except possibly excluding the status bar depending on your status bar and wantsFullscreen settings.
[UIScreen mainScreen].bounds.size returns the bounds unrotated. You can use the convertRect:fromView: method (passing nil for the fromView) on an appropriate on-screen UIView to adjust for rotation and such.
I've been working on an app where we have run into problems like this on a few occasions, so I hope I can help:
First off, make sure you are using a UIViewController to manage your image.
Secondly, make sure your implementation of -shouldAutorotateToInterfaceOrientation: on that view controller returns YES.
Make sure you are using a UIImageView, not a UIImage for your picture, then try setting autoresizesSubviews on the image view's superview (this is the view controller's view) to YES.
If the image resizes, but not to your liking, try messing with the image view's autoresizingMask.
If, after step 3, the image doesn't autoresize, try implementing willRotateToInterfaceOrientation:duration: and programmatically setting the image's frame. Remember that it's superview (the UIViewController's view) hasn't rotated yet, so its frame hasn't updated.
Finally, if that doesn't work, try willAnimateRotationToInterfaceOrientation:duration:, though I'm not quite clear on the difference between this method and the former.
Hope this helps, and let me know your results!
-Bruce
try get your height and width from applicationFrame
UIScreen.mainScreen().applicationFrame.size.height
I got a UIView with 2 subviews. The UIView is set to UIViewAutoresizingFlexibleWidth. Now when it enters layoutSubviews it resizes the frames of the subviews relative to the UIView like so:
rect.size.width = self.frame.size.width - rect.origin.x - textLabel.frame.origin.x;
But a problem occurs in landscape mode cause in portrait mode the self.frame.size.width (and bounds for that matter) respond 768 at start and 788 after it's done rotating. Meaning when it rotates it seems to add 20pixels which I assume is the status bar.
When I hard code 768 it all works as expected. But I don't want that of course. I could store the initial state into a var and use that but I don't think that's the right way to do it.
Anyone have a solution?
Greetings,
in my application I have been facing the same Problem. To solve it I simply used the didRotateFromInterfaceOrientation:method to resize the View when the device is rotated.self.view.frame = CGRectMake(0,0,self.view.bounds.size.width,self.view.bounds.size.height);
Hope this will help.
In my iPhone OS application I want (need) to watch for changes in the device orientation in order to rearrange certain portions of the screen. The approach I used was to use CGRect frame = [UIScreen mainScreen].applicationFrame to get the screen size, and from there calculate the size and / or positioning of other controls (I also tried self.view.frame).
All testing was done so far in Portrait mode, so I could focus on programming the main features and later on just do some adjustments for Landscape. And here enters the problem: In -(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation I added some logging to check the sizes before proceeding, but apparently the values for Width and Height are "wrong" (I say "wrong" because at a first glance the values does not make sense to me).
Here's the output of some logging:
Rotation: Landscape [w=300.000000, h=480.000000]
Rotation: Portrait [w=320.000000, h=460.000000]
The values for "w" and "h" in Landscape seem inverted to me - I was expecting that w=480 and h=300.
What am I doing wrong? The code I used to debug is below.
-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
CGRect frame = [UIScreen mainScreen].applicationFrame;
CGSize size = frame.size;
NSLog(#"%#", [NSString stringWithFormat:#"Rotation: %s [w=%f, h=%f]",
UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? "Portrait" : "Landscape",
size.width, size.height]);
}
The orientation of your device changed, not the physical characteristics of the screen. You basically tipped it on its side, but in reality it is 320 pixels wide (20 of which are not available to you at the moment since the status bar is showing) and 480 pixels tall. If your view is auto-rotating, then the width/height have been translated for you, but when you ask for the actual dimensions of the screen, you get back the actual dimensions of the screen.
This is also why, when working with translated views, it is important to do calculations based on the view's center and the view's bounds and never on the view's frame.
Use self.view.bounds instead.
I've been stumbling over the same problem and with some diagnostic work I discovered that the view's bounds and frame do not accurately reflect the landscape orientation in viewDidLoad (when the device is held in landscape when the view controller is pushed onto the stack), but do so correctly in viewWillAppear: and viewDidAppear:. I just moved my code that needed the dimensions of the frame/bounds from viewDidLoad to viewWillAppear:, and it worked properly.