The Auto Resizing for the UIView's. in Xcode shows the value (0,20,768,1024)however user can't change it in Xcode but if try to repint out the width of the view in your code :
NSLog(#"Board view w %f", self.view.size.width);
NSLog(#"Board view h %f", self.view .size.height);
the values that you get for the width with a portrait are 1024 or 1004
I would like to know in the case of 1004 as width what will happen for the remaining 20 pixels ?
many thanks in advance
You probably are not counting the 20px of the top UIStatusBar.
You can also set the frame manually.
-(void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration{
NSLog(#"didRotateFromInterfaceOrientation");
if( orientation == UIInterfaceOrientationPortrait || fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown){
[moviePlayer.view setFrame:CGRectMake(0,0,768,1024)];
} else {
[moviePlayer.view setFrame:CGRectMake(0,0,1024,768)];
}
}
Related
I've been searching but can't find an answer to this issue I'm having. It seems fairly fundamental, so hopefully someone can explain, or point me towards a previous post.
When adding a viewcontroller's view as a subview of another viewcontroller, I find that the subview's height property goes to zero upon rotation. The width tends to increase as well.
For example, with NSDChildViewController's view set to 50x100 in the xib file...
#implementation ParentViewController
-(void)viewDidLoad
{
[super viewDidLoad];
mChild = [[ChildViewController alloc] initWithNibName:nil
bundle:nil];
[self.view addSubview:mChild.view];
}
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[mChild printFrame];
}
#end
#implementation ChildViewController
-(void)printFrame
{
NSLog(#"%s %#",__FUNCTION__, NSStringFromCGRect(self.view.frame));
}
#end
The logging for respective orientations portrait->landscape->portrait is as follows:
-[ChildViewController printFrame] {{0, 0}, {50, 100}}
-[ChildViewController printFrame] {{0, 0}, {298, 0}}
-[ChildViewController printFrame] {{0, 0}, {50, 248}}
Why does this happen and how can I prevent it? Presently it's causing me trouble whilst trying to programmatically layout viewcontrollers as subviews. The only solution I've found so far is to force the size property back to 50x100 using something like this...
-(void)forceSize
{
CGRect frame = self.view.frame;
frame.size.width=50;
frame.size.height=100;
self.view.frame=frame;
}
but the above seems ludicrous. Any help appreciated.
Your parent view is automatically resizing its child views when its frame changes. In this case, the parent view's frame is changing when the device switches between portrait and landscape mode.
You appear to be testing on a 4-inch iPhone device (or simulator), so the dimensions we're playing with are: 320 x 568. The parent view uses up the full width and height of the screen.
Here's what's happening:
Before rotation from portrait to landscape:
widthDifference = parentViewWidth - originalChildViewWidth // 270 (320 - 50)
heightDifference = parentViewHeight - originalChildViewHeight // 468 (568 - 100)
After rotation from portrait to landscape:
childLandscapeViewWidth = parentViewHeight - widthDifference // 298 (568 - 270)
childLandscapeViewHeight = parentViewWidth - heightDifference // -148 (320 - 468)
// (but height cannot be < 0, so this is automatically set to 0)
So in landscape mode we end up with the child view's width = 298 and height = 0
Before rotation from landscape to portrait:
widthDifference = parentViewWidth - childLandscapeViewWidth // 270 (568 - 298)
heightDifference = parentViewHeight - childLandscapeViewHeight // 320 (320 - 0)
After rotation from landscape to portrait:
childPortraitViewWidth = parentViewWidth - widthDifference // 50 (320 - 270)
childPortraitViewHeight = parentViewHeight - heightDifference // 248 (568 - 320)
And ultimately we end up with the child view's width = 50 and height = 248
So, to put a stop to this craziness set autoresizesSubviews on the parent view (which is YES by default) to NO like so:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.autoresizesSubviews = NO;
...
}
I've searched a lot about how can I determine the actual view size dynamically in the viewDidLoad method.
Here is my approach which seems to be work on both iOS6 and iOS7 with both Landscape and Portrait mode.
Is there a better solution for that?
Here is my code:
- (CGSize)actualSize {
CGFloat widht;
CGFloat height;
// Determin height and widht
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationLandscapeRight || orientation == UIDeviceOrientationLandscapeLeft) {
widht = kHeightSelfView;
height = kWidthSelfView;
} else {
widht = kWidthSelfView;
height = kHeightSelfView;
}
// Determin navigationbar height
CGFloat navigationBarHeight = self.navigationController.navigationBarHidden ? .0f : (MIN(self.navigationController.navigationBar.frame.size.height, self.navigationController.navigationBar.frame.size.width));
// Determin navigationbar height
CGFloat statusbarHeight = [DeviceCompatibility isIOS7] ? (MIN(SharedApplication.statusBarFrame.size.width, SharedApplication.statusBarFrame.size.height)) : .0f;
return CGSizeMake(widht, height - navigationBarHeight - statusbarHeight);
}
Typically you should only perform view-based geometry in viewWillAppear. Your view's frame is not yet set in viewDidLoad, but it will be set correctly before viewWillAppear is called.
Instead of picking height & width, you can pick the frame of view like this:
// Adjusts the frame of the child view.
CGRect frame = self.view.frame;
CGRect linkedFrame = scene.view.frame;
linkedFrame.origin.x -= frame.origin.x;
linkedFrame.origin.y -= frame.origin.y;
and then you can make them flexible so that they will resize properly :
// The scene's main view must be made flexible so it will resize properly
// in the container.
scene.view.autoresizingMask = (UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight);
Let me know if this is not what you need :)
I am trying to have a UIView centered at the middle of the screen that is 320x240 when the device is in the landscape orientation and 240x320 when in the portrait orientation.
For example:
If I let UIKit's layout system do it on its own, I get this when rotating landscape:
And if I try to pin the width and height, I get this:
Basically, is there any way to keep the dimensions of an object during a rotation (but still rotate the object)? Preferably using only Interface Builder, and/or a minimal amount of code if that is not possible.
I think JeffCompton is right: there is no way for you to change the size of your view given the orientation using just the XIB / Autolayouts / Autoresizing masks.
I think the simplest way to do that is:
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[UIView animateWithDuration:0.3 animations:^(void) {
if(UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
self.yourView.frame = CGRectMake([UIScreen mainScreen].frame.size.width-320/2,[UIScreen mainScreen].frame.size.height-240/2,320,240);
} else {
self.yourView.frame = CGRectMake([UIScreen mainScreen].frame.size.width-240/2,[UIScreen mainScreen].frame.size.height-320/2,240,320);
}
}];
}
I am using UIViewController for display my view. My view have been created in interface builder.
Right now these are next parameters for view:
width: 568
height: 320
Orientation: Landscape
in ViewController I have next code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
in info.plist I have added just two interface orientation right and left.
but when I try to output width of my view in code I get 320 and when I try to output height it write down in console 568 but I expect 320 instead.
I don't know why it works like this. Any suggestions?
even if I add this:
[self.view setFrame:CGRectMake(0, 0, 568, 320)]; in viewDidLoad method. even then I have inccorect height
I need to know width size I use in this method:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
CGFloat width = 0.0f;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
width = 568.0f;
} else {
width = 1024.0f;
}
NSInteger page = scrollView.contentOffset.x / width;
NSLog(#"%d", page);
}
Right now I use hardcode variable of width, but how come. Why I can't use self.view.frame.size.width because the sides swop each other - because.
Maybe you're printing width and height in the viewDidLoad method before the orientation occurs. Try to print it on viewWillAppear or with performSelector:afterDelay:
Another thing that might affect the dimension of the view is how you set the autoresizing mask on the interface builder (the red arrows below the x,y,height,width section on the right panel)
Please add LaunchScreen.storyboard in your project and set it as your Launch Screen under
Targets > General > App Icons and Launch Images > Launch Screen file.
In many situation need to rotate the controller and is not working.
Right now I have the inverse of the problem: it is rotating, and I want to disable.
In that ViewController I have this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
but it is auto-rotating, because not this UIViewController is asked, but his parent in UI tree. Maybe that is the problem. The root controller must return Yes for all cases, because there are a few other UIViewControllers on the stack, which has / must have Portait / Landscape support.
I can't / don't want to touch other parts, because ... there are several reasons, for eg: the app is huge, with lot of know bugs and I don't want to make 1 and test it for 1 week, other is the deadline.
Please don't suggest it shouldn't be like this and must rewritten. I know.
How to deal with this controller to force Portait ?
Please read the bolded text too: can't force the whole app to support only Portait for 1 view controller, there are many on stack!
Try marking the app's supported Interface orientations in the properties file to only being portrait. But then of course in that function you just return YES on view controllers that you want to allow rotation. But then when you push it back in the stack the other views should be portrait.
detect the Landscape rotation and rotate to Portait:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
UIInterfaceOrientation appOrientation = [UIApplication sharedApplication].statusBarOrientation;
float width = self.view.bounds.size.width;
float height = self.view.bounds.size.height;
//NSLog(#"width %3.0f, height: %3.0f", width, height);
if((fromInterfaceOrientation == UIInterfaceOrientationPortrait || fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)){
// if is rotated from Portait:
if((appOrientation == UIInterfaceOrientationLandscapeLeft || appOrientation == UIInterfaceOrientationLandscapeRight)){
// to Landscape:
CGAffineTransform transform = self.view.transform;
transform = CGAffineTransformRotate(transform, -(M_PI / 2.0));
self.view.transform = transform;
[self.view setBounds:CGRectMake(0, 0, height, width)];
}
}
else {
// it is rotated from Landscape:
if((appOrientation == UIInterfaceOrientationPortrait || appOrientation == UIInterfaceOrientationPortraitUpsideDown)){
// to Portrait:
CGAffineTransform transform = self.view.transform;
transform = CGAffineTransformRotate(transform, +(M_PI / 2.0));
self.view.transform = transform;
[self.view setBounds:CGRectMake(0, 0, height, width)];
}
}
}
it isn't the best programming paradigm, but it does the trick.
Somebody write similar like tis to accept his answer, or write a better method, if you can!