UIScrollView не получает новый размер при изменении ориентации - PullRequest
7 голосов
/ 11 июля 2010

У меня есть очень простой UIScrollView пример, который просто не делает то, что должен.Не уверен, что это ошибка в API или ошибка в моем коде.

По сути, у меня есть UIViewController с UIScrollView в качестве вида.Когда я добавляю его в UIWindow и меняю ориентацию iPad, я выхожу из системы с размером UIScrollView, о котором неправильно (?) Сообщается.

Вот моя реализация UIViewController:

@implementation CustomViewController
- (void)loadView {
  scrollView = [[[UIScrollView alloc] init] autorelease];
  scrollView.delegate = self;
  scrollView.backgroundColor = [UIColor redColor];
  self.view = scrollView;
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
  CGSize rect = scrollView.frame.size;
  NSLog(@"will rotate w%f h%f", rect.width, rect.height);
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
  CGSize rect = scrollView.frame.size;
  NSLog(@"will animate rotation w%f h%f", rect.width, rect.height);
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
  CGSize rect = scrollView.frame.size;
  NSLog(@"did rotate w%f h%f", rect.width, rect.height);
}

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

@end

Когда я запускаю приведенный выше код, я вижу следующие записи в моей консоли:

2010-07-11 11:03:05.214 Untitled2[6682:207] will rotate w768.000000 h1004.000000
2010-07-11 11:03:05.214 Untitled2[6682:207] will animate rotation w748.000000 h1024.000000
2010-07-11 11:03:05.619 Untitled2[6682:207] did rotate w748.000000 h1024.000000
2010-07-11 11:03:07.951 Untitled2[6682:207] will rotate w748.000000 h1024.000000
2010-07-11 11:03:07.958 Untitled2[6682:207] will animate rotation w768.000000 h1004.000000
2010-07-11 11:03:08.367 Untitled2[6682:207] did rotate w768.000000 h1004.000000

Как вы можете видеть, изменения ориентации изменяют размер UIScrollView, но только для разрешенияновая строка состояния.Я ожидаю, что ширина и высота резко изменятся, так как UIScrollView насколько шире, чем он высокий, и наоборот.

Есть ли способ заставить UIScrollView сообщать о его реальном размере?

Ответы [ 5 ]

4 голосов
/ 04 декабря 2011

У меня есть ответ, если вы все еще ищете.Протестируйте bounds , а не фрейм.

Причина: frame является производным свойством границ и преобразования, применяемого для вращения.

2 голосов
/ 08 сентября 2010

Я заметил, что определение нового contentSize в didRotateFromInterfaceOrientation также невозможно, если вы начинаете с файла NIB iPhone вместо выделенного файла iPad NIB: кадры в файле NIB iPhone намного меньше и, следовательно,Расчетная высота контента становится намного больше, чем должна быть, когда вы на самом деле на iPad.Apple ДЕЙСТВИТЕЛЬНО сказала, что я ДОЛЖЕН создать отдельный файл NIB для iPad ...

Итак, я также получаю старые размеры в didRotateFromInterfaceOrientation, но для меня это теперь не проблема, поскольку iOS справляетсявсе хорошо, как только я начинаю с правильным файлом NIB.Тем не менее, мне кажется, что в методе didRotateFromInterfaceOrientation размеры кадра некорректны для текущего представления.

PS.В конце концов я нашел решение, просто используйте уведомления вместо didRotateFromInterfaceOrientation.

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(orientationChanged:)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil];

Затем в методе orientationChanged настройте представления для новых кадров.У меня была одна заключительная проблема: если исходная ориентация отличалась от ориентации в кончике, вид все равно был бы неправильным, я решил это, создав новый файл NIB специально для ландшафтного вида.В методе init ViewController выбирает, какой NIB он загружает, основываясь на текущей ориентации.

2 голосов
/ 11 июля 2010

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

scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
0 голосов
/ 04 января 2012

Я не знаю, поможет ли это вам, потому что я никогда не проверял это, но я думаю, что это может помочь вам

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
self.view = scrollView;
CGSize rect = scrollView.frame.size;
NSLog(@"will rotate w%f h%f", rect.width, rect.height);
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
self.view = scrollView;    
CGSize rect = scrollView.frame.size;
NSLog(@"will animate rotation w%f h%f", rect.width, rect.height);
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
 self.view = scrollView;
 CGSize rect = scrollView.frame.size;
 NSLog(@"did rotate w%f h%f", rect.width, rect.height);
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
 }  
0 голосов
/ 31 июля 2011

Я обычно исправляю это, устанавливая одно значение из contentSize в 0, например CGSizeMake(contentSize.width, 0) для горизонтального обзора.

Чтобы принудительно UIScrollView прокручивать только, например, горизонтальное значение, не подлежащее прокрутке для contentSize to 0> CGSizeMake(contentSize.width, 0).

Надеюсь, это поможет.

...