Вы можете использовать что-то вроде UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)определения ориентации, а затем соответственно использовать размеры.
ОДНАКО, во время изменения ориентации, как в UIViewController's
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
Используйте переданную ориентацию, toInterfaceOrientationпоскольку statusBarOrientation UIApplication по-прежнему будет указывать на старую ориентацию, поскольку она еще не изменилась (поскольку вы находитесь внутри willобработчика событий).
Резюме
По этому поводу есть несколько связанных сообщений, но каждая из них, похоже, указывает на то, что вам необходимо:
- Посмотрите,
[[UIScreen mainScreen] bounds]чтобы получить размеры,
- Проверьте, в какой вы ориентации, и
- Учитывайте высоту строки состояния (если отображается)
Ссылки
Рабочий код
Я обычно не захожу так далеко, но вы пробудили мой интерес. Следующий код должен помочь. Я написал категорию по UIApplication. Я добавил методы класса для получения currentSize или размера в заданной ориентации, что вы бы назвали в UIViewController willRotateToInterfaceOrientation:duration:.
@interface UIApplication (AppDimensions)
+(CGSize) currentSize;
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation;
@end
@implementation UIApplication (AppDimensions)
+(CGSize) currentSize
{
return [UIApplication sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation
{
CGSize size = [UIScreen mainScreen].bounds.size;
UIApplication *application = [UIApplication sharedApplication];
if (UIInterfaceOrientationIsLandscape(orientation))
{
size = CGSizeMake(size.height, size.width);
}
if (application.statusBarHidden == NO)
{
size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height);
}
return size;
}
@end
Использовать код простой вызов [UIApplication currentSize]. Кроме того, я запустил приведенный выше код, поэтому я знаю, что он работает и сообщает правильные ответы во всех ориентациях. Обратите внимание, что я учитываю строку состояния. Интересно, что мне пришлось вычесть MIN из высоты и ширины строки состояния.
Надеюсь это поможет. : D
Другие мысли
Вы можете получить размеры, посмотрев на rootViewControllerсвойство UIWindow . Я смотрел на это в прошлом, и он аналогичным образом сообщает об одинаковых размерах как в портретной, так и в альбомной ориентации, за исключением того, что он сообщает о преобразовании поворота:
(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController] представление]
<UILayoutContainerView: 0xf7296f0; кадр = (0 0; 320 480); преобразование = [0, -1, 1, 0, 0, 0]; авторазмер = W + H; слой = <CALayer: 0xf729b80 >>
(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController] представление]
<UILayoutContainerView: 0xf7296f0; кадр = (0 0; 320 480); авторазмер = W + H; слой = <CALayer: 0xf729b80 >>
Не уверен, как работает ваше приложение, но если вы не используете какой-либо контроллер навигации, у вас может быть UIView под основным видом с максимальной высотой / шириной родительского элемента и увеличивается / уменьшается вместе с родительским элементом. Тогда вы могли бы сделать: [[[[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] subviews] objectAtIndex:0] frame]. В одной строке это выглядит довольно интенсивно, но вы поняли идею.
Однако ... Все же было бы лучше выполнить указанные выше 3 шага под резюме. Начните возиться с UIWindows, и вы обнаружите странные вещи, например, показ UIAlertView изменит ключевое окно UIApplication так, чтобы он указывал на новый UIWindow, созданный UIAlertView. Кто знал? Я сделал это после того, как обнаружил ошибку, полагающуюся на keyWindow, и обнаружил, что она так изменилась!