Неправильное позиционирование после изменения ориентации на iPad - PullRequest
0 голосов
/ 14 января 2011

Возникли некоторые проблемы при изменении ориентации моего приложения для iPadd.
Я написал функцию, которая выкладывает мои подпредставления, чтобы я мог вызывать ее, когда представление отображается или поворачивается.
Функция отлично работает, когда онавызывается функцией viewWillAppear.Но когда функция «willAnimateRotationToInterfaceOrientation» вызывает мою функцию макета («setPositionsForOrientation»), я сталкиваюсь со следующими проблемами:

  • При переходе из портретного в альбомное положение у меня смещение 128px слева
  • При переходе от альбомной к портретной ориентации у меня отрицательное смещение с левой стороны

У меня сложилось впечатление, что новые свойства фрейма как-то не обрабатываются корректно, так как мой UIScrollViews также должен изменить размер, но они этого не делают.

Вот код, который я написал:

- (void)viewWillAppear:(BOOL)animated{
 [self setPositionsForOrientation:self.interfaceOrientation];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 return YES;
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)newInterfaceOrientation duration:(NSTimeInterval)duration {
 [self setPositionsForOrientation:newInterfaceOrientation];
}

- (void)setPositionsForOrientation:(UIInterfaceOrientation)interfaceOrientation {
 // Position the UI elements for landscape mode
 if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
  self.view.frame = CGRectMake(0, 0, 1024, 748);
  self.menubarImage.frame = CGRectMake(0, 0, 1024, 121);
  self.backgroundImage.frame = CGRectMake(0, 0, 1024, 748);
  self.mainCategories.frame = CGRectMake(6, 6, 1012, 55);
  self.subCategories.frame = CGRectMake(58, 79, 960, 30);
  self.moviesContainer.frame = CGRectMake(6, 204, 1012, 456);
  self.searchButton.frame = CGRectMake(935, 709, 80, 30);
 }
 // Position the UI elements for portrait mode
 else {
  self.view.frame = CGRectMake(0, 0, 768, 1004);
  self.menubarImage.frame = CGRectMake(0, 256, 768, 121);
  self.toolbarImage.frame = CGRectMake(0, 924, 768, 80);
  self.backgroundImage.frame = CGRectMake(0, 256, 768, 748);
  self.mainCategories.frame = CGRectMake(6, 262, 756, 55);
  self.subCategories.frame = CGRectMake(58, 335, 704, 30);
  self.moviesContainer.frame = CGRectMake(6, 460, 756, 456);
  self.searchButton.frame = CGRectMake(680, 963, 80, 30);
 }
}

А вот несколько картинок, иллюстрирующих мою проблему ..

Макет в IB(Все подпредставления имеют contentMode, установленный в верхний левый угол)

http://www.abload.de/image.php?img=interfacebuilderl9ey.png 

Режим портрета отображается правильно / странно

http://www.abload.de/image.php?img=portrait_oklxf1.png
http://www.abload.de/image.php?img=portrait_failma8y.png

Режим ландшафта отображается правильно / странно

http://www.abload.de/image.php?img=landscape_ok4z2l.png
http://www.abload.de/image.php?img=landscape_failvzuy.png

Что я сделал не так и что более важно, как я могу это исправить?
Я нашел этот пост, который описывает обычный способ, но я не понимаю, как я могу переопределитьМой метод view "layoutSubviews", так как представление является просто свойством моего UIViewController.

Ответы [ 2 ]

0 голосов
/ 26 января 2011

Я добавил следующий код в класс MyView в файле .m, и это помогло мне избавиться от страданий:

- (void)awakeFromNib
{
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
0 голосов
/ 14 января 2011

Если вы хотите создать свой собственный подкласс UIView и установить для него UIViewController, чтобы вы могли реализовать метод layoutSubviews, это очень просто!

UIViewController не создает представление, оно ожидает, что пользователь установит представление, но при использовании Interface BUilder для нас уже установлен UIView.

Чтобы изменить вид, выполните:

  • Создайте свой подкласс, здесь я предполагаю, что он называется MyView, и поместите туда все ваши элементы пользовательского интерфейса (панели инструментов, кнопки и т. Д.).
  • Откройте файл вашего контроллера представления в IB (* .xib)
  • Выберите вид (вид, который мы меняем)
  • Перейти к инспектору идентификации (или нажмите Cmd + 4)
  • Введите «MyView» в поле идентификации класса

Поскольку все элементы пользовательского интерфейса отображаются в виде ivar, вы больше не можете получить к ним доступ из UIViewController, верно? Итак, убедитесь, что у вас есть правильные методы доступа / свойства и методы для обработки вашего представления (и его ivars) из UIViewController. ;)

alt text

Удачи;)

EDIT: 2011/01/17

Когда вы находитесь в вашем контроллере и делаете [self.view xyz], вы получаете предупреждение правильно? Это потому, что представление UIViewController объявлено как объект UIView. И вы создали подкласс UIView и установили его в IB. Поэтому каждый раз, когда вы получаете доступ к представлению, вы должны привести его к исполнению, иначе компилятор будет думать, что это все еще обычный UIView, у которого нет методов, которые вы объявили в MyView. Делай так:

[(MyView *)self.view xyz]; //and for that don't forget to #import "MyView.h"

Это должно работать. Но я не понимаю, почему тогда получилось: «тип свойства« view »не соответствует суперклассу« UIViewController »тип свойства» Сначала попробуйте то, что я только что сказал;) Вы уверены, что объявили MyView как:

@interface MyView: UIView{
...
}
@property (...) XYZ *xyz;
...
@end
...