Вы можете использовать что-то вроде 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, и обнаружил, что она так изменилась!
applicationFrame
вместоbounds
(на UIScreen), вам не нужно вычитать высоту строки состояния.mainScreen().bounds.size
стал зависимым от ориентации, начиная с iOS 8,Это мой код решения! Этот метод можно добавить к классу Category NSObject, или вы можете определить верхний настраиваемый класс UIViewController и позволить всем другим вашим UIViewController унаследовать его.
Обратите внимание , что после IOS8, как говорится в Apple Document из свойства границ UIScreen :
поэтому для рассмотрения совместимости мы должны определить версию IOS и внести изменения, как показано ниже:
источник
Вот удобный макрос:
источник
В iOS 8+ вы должны использовать
viewWillTransitionToSize:withTransitionCoordinator
метод:Это заменяет устаревший метод анимации, который не давал информации о размере:
источник
В iOS 8 границы экрана теперь возвращаются правильно для текущей ориентации. Это означает, что iPad в альбомной ориентации [UIScreen mainScreen] .bounds вернет 768 на iOS <= 7 и 1024 на iOS 8.
Следующее возвращает правильную высоту и ширину для всех выпущенных версий.
источник
если вам нужен размер, зависящий от ориентации, и у вас есть представление, вы можете просто использовать:
источник
Я написал категорию
UIScreen
, которая работает на всех версиях IOS, так что вы можете использовать его как это:[[UIScreen mainScreen] currentScreenSize]
.источник
Вот быстрый способ получить размеры экрана в зависимости от ориентации:
Они включены как стандартная функция в мой проект:
https://github.com/goktugyil/EZSwiftExtensions
источник
источник
Однако в iOS 8.0.2:
источник
используйте -> setNeedsDisplay () для представления, размер которого вы хотите изменить.
источник