If your device (simulator or iPad) is in landscape orientation and you start the app while querying the width you get wrong results. One should get 1024 but in fact I'm getting 768 which is completely wrong. On iOS 8 this does work as expected. On iPhone and iOS 7 the view is first in portrait but then changes quickly to landscape which works for my case.
In viewDidLoad I'm getting the the size with View.Bounds.Size.Width. If you rotate the device and query the data in didRotateFromInterfaceOrientation the data is correct. For my app I don't need this in viewDidLoad, but in another method. But in viewDidLoad it seems to be the same behavior.
What's wrong here? How do I get the correct width of the view on iOS 7 and iOS 8?
You should try getting the width in viewDidLayoutSubviews: or any other method that comes after that in the view hierarchy such as viewDidAppear:
Hope this helps you.
Related
I have the weirdest problem specific to a iPhone 6 device. It's related to doing transform on a UIView.
If I do something like this on my UIView:
view.transform = CGAffineTransformMakeRotation(3.14/10)
Then the view disappears entirely. On my iPhone 5, then the view rotates as it should, but on the iPhone 6 it disappears entirely.
Any animation using transform also works perfectly on my iPhone 5 but on my iPhone 6 it doesn't show and sometimes shows "sharded" views of what I'm trying to animate.
This is iPhone 6 specific and only occurs on the device and NOT in the simulator.
Any suggestions on what this could be about?
It seems likely that something is using the frame of the view, which is undefined when you have a non-identify transform. For example, there might be a layoutSubviews method or constraint which is interacting badly with your view (It's better in iOS 8, but perhaps you ran into a yet-unsolved case). It's hard to tell what exactly is going on since you didn't supply a completely example.
You might try a tool like Xcode's view inspector or Reveal which can show you where your view is ending up and what constraints are acting on it. If that's not instructive, you should make a minimal example and post it.
It could also be differences in iOS version. Do your devices and simulators share the same point release?
It ended up being RubyMotion specific, so sorry for posting it with iOS tags - http://community.rubymotion.com/t/transform-making-uiview-disappear-on-iphone-6-device/344/4.
I just started testing my app on an iPad 2 thats still running iOS 7, because thats what I had lying around. As soon as I open up the app, the main view under the UINavigationController is offset and too small. Heres a picture of what I'm talking about:
The whole screen should be the light color. I use [UIScreen mainScreen].bounds to make the lighter view. I'm compiling this on the iOS 8.2 SDK. After logging the width and height, it seems like they're inverted. Is that how iOS 7 handles things? I think just checking if its running iOS 7 and swapping them will work, but I want to make sure this is the problem. Thanks.
EDIT:
Swapping them worked, but when I go to another view, that view is also rotated, and those are normal views.
iOS8 bounds are relative to orientation thus a device in landscape will have different bounds from the same one on portrait , in iOS7 this does not happen, the bounds are the same no matter if you are in portrait or landscape
See this answer
My root view controller is a tab view controller. My app is landscape mode only. It's set on landscape both in the project settings and in the storyboard for each VC including the root. In viewDidLoad, I have:
NSLog(#"width of view in didappear:%f",self.view.frame.size.width);
and the same code in viewDidAppear. In viewDidLoad in iOS 8, that line prints out 480. In iOs 7, it prints out 320(the width of the screen in portrait mode) but in viewDidAppear, it prints out 480 which is correct. Yes it is the same device for all of you out there who are always in search of 'precise' details.
Why is the view still in portrait in viewDidLoad in ios7 but not in ios8? What can be done? I set up my whole view in viewDidLoad because I only need to do it once and so can't migrate it to viewDidAppear or other places.
It's a curious difference between iOS 7 and 8 if that's the case. I'm guessing it's the same device type but physically different items? Or are you really running iOS 7 & 8 on the same device?
So you could theoretically still have setting differences. I.e. iOS 7 device locked in portrait, etc.
If the setup is really as you say, a boolean property would help you to run in viewDidAppear. I just provided an example of how that could be done here: https://stackoverflow.com/a/27867549/1111233
Basically, viewDidLoad is run before the UIElements are loaded and placed on screen, so that's why you are getting the wrong size. As far as the difference between iOS7 and iOS8, I guess apple slightly changed the internals, but in any case you should definitely move your graphics code to viewWillAppear. viewWillAppear is run when the graphics are loaded and works the same as viewDidLoad
use bounds
CGRect rect = [[UIScreen mainScreen] bounds];
NSLog(#"width of view in didappear:%f",rect.size.width);
The frame is relevant to the parent view. The very top view is UIWindow, which in iOS 8 became rotation dependent. In landscape the frame and the bounds will therefore be different in iOS 7, but the same in iOS 8. If you use bounds instead of frame, it should give the same result for both iOS versions, given that the objects are not rotated some number of degrees.
Hi I am facing a strange issue. I am adding a UIViewController to Window's RootViewController.
I have set my ViewControllerXIB's autoresizing as MaskAll. When I run my project on iPad with iOS 7 in Landscape mode, I get screen size as (1024,768). But when I run on iPad with iOS 8, I get the screen size as (768,1024). I am not able to figure it out why this is happening. Due to this my ViewController's subviews are not loading with proper screen size since I am passing them the ViewController's screen size.
Can anybody help me out on this?
But when I run on iPad with iOS 8, I get the screen size as (768,1024).
It's because in iOS 7 and before, app rotation involves applying a rotation transform to the root view controller's view, while the window and screen remain pinned to the device. But in iOS 8, the entire app literally rotates. This is a major change and it can indeed break your existing code if you were expecting the rotation transform. On the other hand it's also much better - in iOS 8, rotation means that the screen, the window, the root view controller's view all simply change size (they swap their height and width) - and that means that if your app launches into landscape it has the correct dimensions right from the start.
If you need pure device coordinates in iOS 8 you can get them with the new UICoordinateSpace protocol (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICoordinateSpace_protocol/).
I'm creating a cocos2d game on iOS that uses the accelerometer. I just started testing on an iphone 5 and for some reason, it's reversing the accelerometer data - basically it behaves as if the screen orientation is 180 degrees flipped from how it actually is, tilting down causes it to send things up, left goes right etc.
It works fine on my iphone 4 running iOS 5 and on both my ipad running iOS 5 and my ipad running iOS 6. Not sure if it's an issue with just the iphone 5 or all iphones running iOS 6.
I can't find any mention of this issue online, wondering if anyone else is running into this and if you know of a solution.
OK I figured out what was going on. In iOS 6 the willRotateToInterfaceOrientation method is deprecated and no longer gets called. I had code in there to do two things - detect which landscape orientation the phone was loading into and adjust the variables accordingly, and to prevent the phone from flipping the orientation during gameplay (it's a tilt-to-move game). The reason everything was behaving as if the view was upside-down was because it was, and the phone's orientation was locked, and my code to correct for that wasn't being called. Here's what Apple says about willRotateToInterfaceOrientation:
The willRotateToInterfaceOrientation:duration:,
willAnimateRotationToInterfaceOrientation:duration:, and
didRotateFromInterfaceOrientation: methods are no longer called on any
view controller that makes a full screen presentation over itself—for
example, by calling presentViewController:animated:completion:. You
should make sure that your apps are not using these methods to manage
the layout of any subviews. Instead, they should use the view
controller’s viewWillLayoutSubviews method and adjust the layout using
the view’s bounds rectangle.
Now I just need to figure out how to use the willLayoutSubviews method to replicate my original functionality.