如何获得与方向相关的屏幕高度和宽度?

Mus*_*sis 96 ios

我正在尝试以编程方式确定我的应用程序的当前高度和宽度.我用这个:

CGRect screenRect = [[UIScreen mainScreen] bounds];
Run Code Online (Sandbox Code Playgroud)

但无论设备是纵向还是横向,这都会产生320的宽度和480的高度.如何确定主屏幕的当前宽度和高度(即取决于设备方向)?

Sam*_*Sam 164

您可以使用类似的方法UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)来确定方向,然后相应地使用尺寸.

但是,在UIViewController中的方向更改期间

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 
                                 duration:(NSTimeInterval)duration
Run Code Online (Sandbox Code Playgroud)

使用传入的方向,toInterfaceOrientation因为UIApplication的statusBarOrientation仍将指向旧方向,因为它尚未更改(因为您在will事件处理程序中).

摘要

有几个相关的帖子,但每个都似乎表明你必须:

  1. 看看[[UIScreen mainScreen] bounds]得到的尺寸,
  2. 检查你的方向,和
  3. 帐户状态栏高度(如果显示)

链接

工作守则

我通常不会走这么远,但你引起了我的兴趣.以下代码应该可以解决问题.我写了一篇关于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
Run Code Online (Sandbox Code Playgroud)

要使用代码简单调用[UIApplication currentSize].此外,我运行上面的代码,所以我知道它的工作原理并报告所有方向的正确响应.请注意,我考虑状态栏.有趣的是,我不得不减去状态栏高度和宽度的MIN.

希望这可以帮助.:d

其他想法

您可以通过查看UIWindow的rootViewController属性来获取维度.我在过去看过这个,它同样在纵向和横向上报告相同的尺寸,除了它报告有旋转变换:

(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController] view]

<UILayoutContainerView:0xf7296f0; frame =(0 0; 320 480); transform = [0,-1,1,0,0,0]; autoresize = W + H; layer = <CALayer:0xf729b80 >>

(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController] view]

<UILayoutContainerView:0xf7296f0; frame =(0 0; 320 480); autoresize = W + H; layer = <CALayer:0xf729b80 >>

不确定你的应用程序是如何工作的,但是如果你没有使用某种类型的导航控制器,你可以在主视图下面有一个UIView,其中父级的最大高度/宽度与父级一起增长/缩小.然后你可以这样做:[[[[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] subviews] objectAtIndex:0] frame].在一条线上看起来非常激烈,但你明白了.

但是......在摘要下进行上述3个步骤仍然会更好.开始搞乱UIWindows,你会发现奇怪的东西,比如显示UIAlertView将改变UIApplication的keywindow指向UIAlertView创建的新UIWindow.谁知道?在找到依赖keyWindow的bug并发现它改变了之后我做了!

  • 这似乎是一个基本的任务,我很难相信我必须破解我自己的代码来确定这样的事情. (5认同)
  • 我会尝试另一种解决方案并重新发布它是否有效.如果你不快速回答这个网站是如此积极,你可能根本不回答.哈哈......:DI希望我的回答至少有帮助.再一次,我会快速尝试别的东西. (2认同)
  • MIN为+1(statusBar ... width,statusBar ... height) (2认同)
  • http://stackoverflow.com/questions/24150359/is-uiscreen-mainscreen-bounds-size-becoming-orientation-dependent-in-ios8`mainScreen().bounds.size`已成为取决于iOS 8的方向 (2认同)

mon*_*jer 39

这是我的解决方案代码!此方法可以添加到NSObject类的Categroy,或者您可以定义Top自定义UIViewController类,并让所有其他UIViewControllers继承它.

-(CGRect)currentScreenBoundsDependOnOrientation
{  

    CGRect screenBounds = [UIScreen mainScreen].bounds ;
    CGFloat width = CGRectGetWidth(screenBounds)  ;
    CGFloat height = CGRectGetHeight(screenBounds) ;
    UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;

    if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
        screenBounds.size = CGSizeMake(width, height);
    }else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
        screenBounds.size = CGSizeMake(height, width);
    }
    return screenBounds ;
}
Run Code Online (Sandbox Code Playgroud)

请注意,在IOS8之后,作为UIScreen的边界属性的Apple Document说:

讨论

此矩形在当前坐标空间中指定,该空间考虑了对设备有效的任何界面旋转.因此,当设备在纵向和横向之间旋转时,此属性的值可能会更改.

所以为了兼顾性,我们应该检测IOS版本并进行如下更改:

#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)

-(CGRect)currentScreenBoundsDependOnOrientation
{  

    CGRect screenBounds = [UIScreen mainScreen].bounds ;
    if(IsIOS8){
        return screenBounds ;
    }
    CGFloat width = CGRectGetWidth(screenBounds)  ;
    CGFloat height = CGRectGetHeight(screenBounds) ;
    UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;

    if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
        screenBounds.size = CGSizeMake(width, height);
    }else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
        screenBounds.size = CGSizeMake(height, width);
    }
    return screenBounds ;
}
Run Code Online (Sandbox Code Playgroud)

  • @Monjer你不应该命名不执行GET请求的方法,用词get作为前缀.currentScreenBoundsDependOnOrientation是该方法的更好名称 (2认同)

Rob*_*aff 30

这是一个方便的宏:

#define SCREEN_WIDTH (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height)
#define SCREEN_HEIGHT (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width)
Run Code Online (Sandbox Code Playgroud)


Mar*_*ngs 14

在iOS 8+中,您应该使用以下viewWillTransitionToSize:withTransitionCoordinator方法:

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    // You can store size in an instance variable for later
    currentSize = size;

    // This is basically an animation block
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {

        // Get the new orientation if you want
        UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];

        // Adjust your views
        [self.myView setFrame:CGRectMake(0, 0, size.width, size.height)];

    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        // Anything else you need to do at the end
    }];
}
Run Code Online (Sandbox Code Playgroud)

这将替换不提供有关大小信息的弃用动画方法:

-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
Run Code Online (Sandbox Code Playgroud)


A.B*_*ger 10

从iOS 8开始,屏幕边界现在返回正确的当前方向.这意味着横向的iPad [UIScreen mainScreen] .bounds将在iOS <= 7上返回768,在iOS 8上返回1024.

以下内容在发布的所有版本上返回正确的高度和宽度.

-(CGRect)currentScreenBoundsDependOnOrientation
{
    NSString *reqSysVer = @"8.0";
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
    if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
        return [UIScreen mainScreen].bounds;

    CGRect screenBounds = [UIScreen mainScreen].bounds ;
    CGFloat width = CGRectGetWidth(screenBounds)  ;
    CGFloat height = CGRectGetHeight(screenBounds) ;
    UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;

    if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
        screenBounds.size = CGSizeMake(width, height);
        NSLog(@"Portrait Height: %f", screenBounds.size.height);
    }else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
        screenBounds.size = CGSizeMake(height, width);
        NSLog(@"Landscape Height: %f", screenBounds.size.height);
    }

    return screenBounds ;
}
Run Code Online (Sandbox Code Playgroud)


Tod*_*Tod 8

如果您想要与方向相关的尺寸并且您有一个视图,您可以使用:

view.bounds.size
Run Code Online (Sandbox Code Playgroud)

  • KISS并不意味着"保持简单和愚蠢" - 哈哈!这意味着"保持简单,愚蠢!" :-) (3认同)

Art*_*eel 5

我为UIScreen所有iOS版本编写了类别,所以你可以像这样使用它:
[[UIScreen mainScreen] currentScreenSize].

@implementation UIScreen (ScreenSize)

- (CGSize)currentScreenSize {
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    CGSize screenSize = screenBounds.size;

    if ( NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1 ) {  
        UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
        if ( UIInterfaceOrientationIsLandscape(interfaceOrientation) ) {
            screenSize = CGSizeMake(screenSize.height, screenSize.width);
        }
    }

    return screenSize;
}

@end
Run Code Online (Sandbox Code Playgroud)


Esq*_*uth 5

这是一种获取取向相关屏幕尺寸的Swift方法:

var screenWidth: CGFloat {
    if UIInterfaceOrientationIsPortrait(screenOrientation) {
        return UIScreen.mainScreen().bounds.size.width
    } else {
        return UIScreen.mainScreen().bounds.size.height
    }
}
var screenHeight: CGFloat {
    if UIInterfaceOrientationIsPortrait(screenOrientation) {
        return UIScreen.mainScreen().bounds.size.height
    } else {
        return UIScreen.mainScreen().bounds.size.width
    }
}
var screenOrientation: UIInterfaceOrientation {
    return UIApplication.sharedApplication().statusBarOrientation
}
Run Code Online (Sandbox Code Playgroud)

这些作为我的项目的标准功能包括在内:

https://github.com/goktugyil/EZSwiftExtensions