Изменение 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 пикселей были ограблены от ширины и заданы на высоту. Может ли кто-нибудь объяснить это мне и как я мог / должен был кодировать элементы в моем представлении, чтобы учесть это?

Моя раскадровка выглядит следующим образом:

введите описание изображения здесь

Мое начальное представление: введите описание изображения здесь

После первого поворота (все еще хорошо) введите описание изображения здесь

Вращение назад к портрету (все завинчивается из-за значений границ) введите описание изображения здесь

One Solution collect form web for “Изменение iOS меняется после поворота на пейзаж, затем обратно к портрету”

Вы должны в значительной степени никогда не делать макет в willRotateToInterfaceOrientation:duration: Когда система отправит вас, вы будете willRotateToInterfaceOrientation:duration: он не обновил фрейм вашего представления до его нового размера . Поэтому, консультируясь с self.view.frame , вы используете рамку для текущей (старой) ориентации, а не для рамки для новой (еще не повернутой) ориентации.

Вы также не должны делать макет в viewDidAppear: потому что к тому времени, когда вы получите viewDidAppear: ваше представление уже находится на экране. Вам нужно сделать макет, прежде чем ваше представление появится на экране.

Вам нужно сделать свой макет соответствующим методом. Лучшее место для макета – это метод UIView пользовательского подкласса UIView . Положив его, ваша логика просмотра будет отделена от логики контроллера.

Следующим лучшим местом для вашего макета является метод viewWillLayoutSubviews или viewDidLayoutSubviews вашего контроллера представлений.

Если вы поместите свой код макета в layoutSubviews , viewWillLayoutSubviews или viewDidLayoutSubviews , система автоматически вызовет этот метод до того, как ваше представление появится на экране, и внутри блока анимации авторотации. В обоих случаях он будет обновлять рамку вашего представления для правильной ориентации перед отправкой вам сообщения.

Если вам нужно сделать что-то вроде скрытия представления до начала анимации авторотации и снова показать его после, вы можете сделать это в willRotateToInterfaceOrientation:duration: and didRotateFromInterfaceOrientation:

Если вы хотите выполнять специальные анимации только во время авторотации, а не во время первоначального макета представления, вы можете сделать это в willAnimateRotationToInterfaceOrientation:duration: который вызывается внутри блока анимации авторотации.

Вы можете найти этот ответ полезным: UIViewController возвращает недопустимый фрейм?

  • Как переместить FPPopover как можно ниже? Если я нажму слишком низко, он вернется к началу
  • iOS Core Animation: неправильная опорная точка для вращения
  • UITableViewController - выпадающий список таблиц, чтобы показать новый UIView
  • Есть ли способ настроить Sharekit?
  • UITapGestureRecognizer в UIView и его подвью ответят вместе, когда Subview забит
  • Как получить нижнюю координату y
  • Как удалить ограничения из всех подзонов внутри моего супервизора?
  • Где обновлять ограничения Autolayout при изменении размера?
  • Почему addSubview: не сохранять вид?
  • Изменить размер UIView внутри UIScrollView с помощью AutoLayout для прокрутки?
  • Как изменить размер UIView для универсального приложения с помощью Autolayout
  • Как я могу оживить контейнер UIView, чтобы уменьшить его высоту?
  • PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.