旋转到横向后,iOS边界会改变,然后回到纵向

当我的应用程序启动时,我的视图边界的NSLog显示如下:

NSLog(@"My view frame: %@", NSStringFromCGRect(self.view.bounds)); My view frame: {{0, 0}, {320, 548}} 

然后我旋转模拟器并得到以下内容:

 NSLog(@"My view frame: %@", NSStringFromCGRect(self.view.bounds)); My view frame: {{0, 0}, {320, 548}} 

然后,当我将模拟器旋转回portait,我得到这个:

 NSLog(@"My view frame: %@", NSStringFromCGRect(self.view.bounds)); My view frame: {{0, 0}, {568, 300}} 

我用来调整元素的两种方法是这些,他们还没有完成,因为我目前正在修复它们为新的iPhone。

 -(void) resizeForLandscape { newsLabel = (UILabel *)[self.view viewWithTag:50]; weatherLabel = (UILabel *)[self.view viewWithTag:51]; sportsLabel = (UILabel *)[self.view viewWithTag:52]; entertainmentLabel = (UILabel *)[self.view viewWithTag:53]; videosLabel = (UILabel *)[self.view viewWithTag:54]; moreLabel = (UILabel *)[self.view viewWithTag:55]; NSLog(@"resizeForLandscape called"); webView.frame = CGRectMake(0, 31, self.view.frame.size.width, self.view.frame.size.height - 75); button.frame = CGRectMake(0, 0, image.size.width -30, image.size.height -15); myLabel.frame = CGRectMake(230, 100, 80, 21); label.frame = CGRectMake(0, 0, self.view.bounds.size.height + 15, 30); NSLog(@"My view frame: %@", NSStringFromCGRect(self.view.bounds)); NSLog(@"my status bar height is %f", [UIApplication sharedApplication].statusBarFrame.size.height); NSLog(@"my status bar width is %f", [UIApplication sharedApplication].statusBarFrame.size.width); newsLabel.frame = CGRectMake((self.view.bounds.size.height - 346) / 2 + 12, self.view.bounds.size.width - 38, 43, 21); weatherLabel.frame = CGRectMake(newsLabel.frame.origin.x + 64, self.view.bounds.size.width - 38, 42, 21); sportsLabel.frame = CGRectMake(newsLabel.frame.origin.x + 126, self.view.bounds.size.width - 38, 42, 21); entertainmentLabel.frame = CGRectMake(newsLabel.frame.origin.x + 185, self.view.bounds.size.width - 38, 66, 21); videosLabel.frame = CGRectMake(newsLabel.frame.origin.x + 269, self.view.bounds.size.width - 38, 42, 21); moreLabel.frame = CGRectMake(newsLabel.frame.origin.x + 325, self.view.bounds.size.width - 38, 42, 21); spacer1.width = (self.view.bounds.size.height - 346) / 2; spacer2.width = 40; spacer3.width = 28; spacer4.width = 42; spacer5.width = 35; spacer6.width = 24; } -(void) resizeForPortrait { newsLabel = (UILabel *)[self.view viewWithTag:50]; weatherLabel = (UILabel *)[self.view viewWithTag:51]; sportsLabel = (UILabel *)[self.view viewWithTag:52]; entertainmentLabel = (UILabel *)[self.view viewWithTag:53]; videosLabel = (UILabel *)[self.view viewWithTag:54]; moreLabel = (UILabel *)[self.view viewWithTag:55]; NSLog(@"resizeForPortrait called"); webView.frame = CGRectMake(0, 44, self.view.frame.size.width, self.view.frame.size.height -88); button.frame = CGRectMake(0, 0, image.size.width, image.size.height); myLabel.frame = CGRectMake(145, 152, 80, 21); label.frame = CGRectMake(0, 0, 315, 40); NSLog(@"My view frame: %@", NSStringFromCGRect(self.view.bounds)); NSLog(@"my status bar height is %f", [UIApplication sharedApplication].statusBarFrame.size.height); NSLog(@"my status bar width is %f", [UIApplication sharedApplication].statusBarFrame.size.width); float myWidth = MIN(self.view.bounds.size.height, self.view.bounds.size.width); float myHeight = MAX(self.view.bounds.size.height, self.view.bounds.size.width); newsLabel.frame = CGRectMake(newsLabel.frame.origin.x, myHeight - 18, 43, 21); weatherLabel.frame = CGRectMake(newsLabel.frame.origin.x + 43, myHeight - 18, 42, 21); sportsLabel.frame = CGRectMake(newsLabel.frame.origin.x + 97, myHeight - 18, 42, 21); entertainmentLabel.frame = CGRectMake(newsLabel.frame.origin.x + 138, myHeight - 18, 66, 21); videosLabel.frame = CGRectMake(newsLabel.frame.origin.x + 213, myHeight - 18, 42, 21); moreLabel.frame = CGRectMake(newsLabel.frame.origin.x + 258, myHeight - 18, 42, 21); spacer1.width = (myWidth - 346) / 2; spacer2.width = 20; spacer3.width = 18; spacer4.width = 25; spacer5.width = 28; spacer6.width = 14; } 

调用人:

 -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) { [self resizeForLandscape]; } else { [self resizeForPortrait]; } } - (void) getOrientationandResize { if (UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) { [self resizeForLandscape]; } else { [self resizeForPortrait]; } } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self getOrientationandResize]; } 

我的头即将爆炸。 不仅视图颠倒了,而且还有20个像素从宽度上被抢走并被赋予高度。 任何人都可以解释这个给我,我怎么可以/应该编码在我看来的元素来解释它?

我的故事板如下:

在这里输入图像说明

我最初的看法: 在这里输入图像说明

第一次轮换后(仍然不错) 在这里输入图像说明

旋转回肖像(因为边界值而全部搞砸了) 在这里输入图像说明

您应该几乎从不在willRotateToInterfaceOrientation:duration:进行布局willRotateToInterfaceOrientation:duration: 当系统向您发送willRotateToInterfaceOrientation:duration:它并没有将视图的帧更新为新的大小 。 因此,通过咨询self.view.frame ,您将使用框架作为当前(旧)方向, 而不是用于新(未旋转到)方向的框架。

你也不应该在viewDidAppear:做布局,因为当你收到viewDidAppear: ,你的视图已经在屏幕上了。 您需要视图在屏幕上之前进行布局。

你需要用适当的方法做你的布局。 布局的最佳位置是在自定义UIView子类的layoutSubviews方法中。 放在那里让你的视图逻辑与你的控制器逻辑分开。

布局的下一个最佳位置是视图控制器的viewWillLayoutSubviewsviewDidLayoutSubviews方法。

如果将布局代码置于layoutSubviewsviewWillLayoutSubviewsviewDidLayoutSubviews ,系统将自动调用该方法,然后视图出现在屏幕上,并位于自动旋转的animation块内。 在这两种情况下,它都会在向您发送消息之前更新您的视图框架以获取正确的方向。

如果您需要在自动旋转animation开始之前做一些隐藏视图的操作,并在之后再次显示,可以在willRotateToInterfaceOrientation:duration:didRotateFromInterfaceOrientation:

如果只想在自动旋转过程中执行特殊animation,而不是在初始视图布局过程中执行特殊animation,则可以在自动旋转的animation块中调用的willAnimateRotationToInterfaceOrientation:duration:中执行此操作。

你可能会发现这个答案有帮助: UIViewController返回无效的框架?