I have a scene with a UIButton placed on it which has these parameters:
origin=(x=131, y=136) size=(width=760, height=570)
In viewDidLoad I put these coordinates into a CGRect variable:
CGRect myRect = _mainImage.frame;
When checking myRect in Landscape orientation with NSLog I get this:
origin=(x=131, y=136) size=(width=504, height=570)
But the width value 504 is the value for Portrait orientation.
When using the same thing in Portrait orientation I´m getting the same values.
Any ideas?
Related
This is only an iOS 8 problem, the keyboard displays correctly in iOS 7 with device orientation change. My application supports both portrait and landscape orientation and uses autolayout.
If I push a UIViewController subclass that contains a UITextField subclass onto a navigation stack and the UITextField becomes the first responder in portrait orientation then the default keyboard displays correctly. However, if I rotate the device to landscape orientation then the UIViewController subview layouts are displayed correctly but the keyboard is displayed in the top center of the screen. The keyboard's orientation is correct for landscape orientation but it's frame width is the same width as expected for portrait orientation. If I set the app orientation to only landscape orientation then the keyboard does not display correctly. This is only a problem for iOS 8 orientation change.
Prior to iOS 8, the keyboard's location and width/height were always relative to portrait orientation when reported to the app. (e.g. Landscape's keyboard width is in the y direction, ~352 pixels on an iPad.)
As of iOS 8, this has been updated to always have (0,0) at the top left of your (physical) view and the width/height reflect the x/y orientation you would normally expect outside of iOS. If you were previously positioning your keyboard via something like keyboardDidShow's [notification userInfo], you are going to get numbers that don't quite make sense. You can use something along these lines to take into account the pre-iOS8 idiosyncrasies:
- (void)keyboardDidShow: (NSNotification *) notification{
NSDictionary *keyboardInfo = [notification userInfo];
CGSize keyboardSize = [[keyboardInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
float height, width;
if(UIInterfaceOrientationIsPortrait(orientation)){
width = keyboardSize.width;
height = keyboardSize.height;
} else {
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1){
width = keyboardSize.height;
height = keyboardSize.width;
} else {
width = keyboardSize.width;
height = keyboardSize.height;
}
}
// Remainder of function
}
Which can be refactored down to...
- (void)keyboardDidShow: (NSNotification *) notification{
NSDictionary *keyboardInfo = [notification userInfo];
CGSize keyboardSize = [[keyboardInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
float width = keyboardSize.width;
float height = keyboardSize.height;
if(!UIInterfaceOrientationIsPortrait(orientation) && (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1)){
width = keyboardSize.height;
height = keyboardSize.width;
}
// Remainder of function
}
Also, the 8.1 update fixed several landscape/rotation bugs likely related to the above change. Grab the update and see if that solves your issue.
It is is not a bug of iOS8 or iPhone 6. It is problem of the correct migration of old projects to xCode6.
You simply need to add Launch screen interface file base name key to Info.plist file.
Detailed explanation of this case you can find here.
I am having an issue with resizing UIPageViewController in landscape mode.
Here is my scenario:
I have a UIViewController which has a scrollview in it.
I added a UIPageViewController to the scrollview programmatically and it is displaying all my view controllers in each page correctly.
When i change the device orientation to landscape i am correctly changing the content size of the scrollview but the PageViewController is displaying only up to half of its contents. Can you please help me with this one.
Thanks,
Anand.
It looks like you are either not getting the correct orientation of your device or trying to set it in the viewDidLoad function. The following code should correctly set your page view controller's frame to current orientation.
- (void)viewWillLayoutSubviews {
CGRect screenFrame = [[UIScreen mainScreen] applicationFrame];
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
screenFrame = CGRectMake(0, 0, screenFrame.size.height, screenFrame.size.width);
}
//Please don't forget to replace _myPageViewController with your variable
_myPageViewController.frame = screenFrame;
}
Please note that code is getting called from viewWillLayoutSubviews
function.
Background: I wanted to animate the change in my content along with the orientation. My content position is relative to the self.view.bounds.
Problem: In order to animate the content along with the bounds, I would need to know what would the bounds of the view be at the end. I can hard code it but I hope to find a more dynamic way.
Codes: So all animation takes place in willRotateToInterfaceOrientation as per following:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
//centering the image
imageView.frame = CGRectMake(self.view.bounds.origin.x + (self.view.bounds.size.width - image.size.width)/2 , self.view.bounds.origin.y + (self.view.bounds.size.height - image.size.height)/2, image.size.width, image.size.height);
NSLog(#"%d",[[UIDevice currentDevice] orientation]);
NSLog(#"%f", self.view.bounds.origin.x);
NSLog(#"%f", self.view.bounds.origin.y);
NSLog(#"%f", self.view.bounds.size.width);
NSLog(#"%f", self.view.bounds.size.height);
}
The bounds are before the orientation change. Thus, this only works if the transformation is 180 degrees. If I were to use didRotateFromInterfaceOrientation, the animation will be after the orientation change which looks awful.
Use willAnimateRotationToInterfaceOrientation:duration: instead. This method gets called from within the rotation animation block, and all the bounds have been set correctly at this point. Docs.
If you want it dynamic then when you initialize imageView, set the autoresizingMask property so that when the imageView's superview resizes on the rotate the margins can auto resize themselves...
imageView = //init imageView
imageView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
//addtional config
This means you only need to set the frame once then the imageView will always adjust itself to stay in the middle.
Check out the UIView class reference http://developer.apple.com/library/ios/ipad/#documentation/uikit/reference/uiview_class/uiview/uiview.html to see what else you can do with the autoresizingMask property
If I'm understanding you correctly, you just need to swap the X/Y coordinates and width/height in you're CGRectMake, to get your future layout for a 90 degree change. If it's 180 degree change, then it's the same as current
CGRectMake(self.view.bounds.origin.y + (self.view.bounds.size.height - image.size.height)/2 , self.view.bounds.origin.x + (self.view.bounds.size.width - image.size.width)/2, image.size.height, image.size.width);
I have a UIViewController which supports all interface Orientations. The views are created programatically in the loadView() which works so far. All the views added in the loadView() method have the correct size and rotation.
However any views added later on are not rotated correctly. If I add the following UIView
[[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height)] autorelease];
it is only fullscreen if the UIViewController was in portrait mode when the UIView was added. If the device was in landscape mode the UIView is only 748 pixels wide, not the 1024 I would expect. [[UIScreen mainScreen] applicationFrame].size.width delivers 768 pixels or 748 pixels depending on the device's rotation.
So how should I create and add the UIView so it is shown with the full screen size? I would also like to init the UIView's content only for one mode (portrait OR landscape) and have it autoresized for the other mode. I basically need to tell the UIView it is a portrait mode view and should be rotated when added to a landscape view controller.
Since I couldn't init the UIView with the correct size, I just left the initialization code like it was (always creating the view in portrait mode) and resized the UIView later to the parent view's bounds property. Unlike the frame property, bounds seems to return the correct size depending on the current rotation.
I have a big problem concerning the resizing of a derived UIView with a UIScrollView as subview.
In the layoutSubviews message I set the frame of the UIScrollView subview. the UIScrollView contains a UIImageView with a big image which can be moved/pinched and so on. The initial contenSize of the UIScrollView is the initial image size.
So far, so good. Moving and pinching of the image works well. Now I have to change the UIView frame (in my app to maximize the UIView). im doing that in a animation block (beginAnimations/commitAnimations). So I set the new frame (which will update the width & height) an then I call [myView layoutIfNeeded] to force the UIScrollView to update its frame in the layoutSubviews message of my view.
The UIView animates correct to its new frame and if the contentOffset of the UIScrollView is currently x 0, y 0 the UIScrollView frame will be updated properly. but here's my problem: if the contentOffset of the UIScrollView is bigger than x 0, y 0 the UIScrollView will "slide in" from upper left to its final position.
I want that the UIScrollView resizes its frame properly with the parents frame and aligns the content (in my case the UIImageView) right. But how could I achieve that?
after hours of web research i found the solution for this problem:
[UIView setAnimationBeginsFromCurrentState: YES];
this will animate all layers from the current state.