184

iOS 7 と iOS 8 の両方で次のコードを実行しました。

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
BOOL landscape = (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight);
NSLog(@"Currently landscape: %@, width: %.2f, height: %.2f", 
      (landscape ? @"Yes" : @"No"), 
      [[UIScreen mainScreen] bounds].size.width, 
      [[UIScreen mainScreen] bounds].size.height);

以下は iOS 8 の結果です。

Currently landscape: No, width: 320.00, height: 568.00
Currently landscape: Yes, width: 568.00, height: 320.00

iOS 7 での結果との比較:

Currently landscape: No, width: 320.00, height: 568.00
Currently landscape: Yes, width: 320.00, height: 568.00

この変更を指定するドキュメントはありますか? それとも、iOS 8 API の一時的なバグですか?

4

18 に答える 18

59

はい、iOS8 では向きに依存します。

古いバージョンの OS をサポートする必要があるアプリのために、この問題を解決する Util メソッドを作成しました。

+ (CGSize)screenSize {
    CGSize screenSize = [UIScreen mainScreen].bounds.size;
    if ((NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) && UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
        return CGSizeMake(screenSize.height, screenSize.width);
    }
    return screenSize;
}
于 2014-08-01T20:50:54.727 に答える
34

はい、確かに、iOS 8 では画面サイズが向きに依存するようになりました。ただし、サイズを縦向きに固定したい場合があります。これが私のやり方です。

+ (CGRect)screenBoundsFixedToPortraitOrientation {
    UIScreen *screen = [UIScreen mainScreen];

    if ([screen respondsToSelector:@selector(fixedCoordinateSpace)]) {
                    return [screen.coordinateSpace convertRect:screen.bounds toCoordinateSpace:screen.fixedCoordinateSpace];
    } 
    return screen.bounds;
}
于 2014-08-08T18:11:07.290 に答える
32

はい、向きに依存するようになりました。

上記の回答のいくつかよりも、方向に依存しない方法で画面サイズを取得する以下の方法を好みます。これは、より単純であり、方向コードに依存しないためです (状態は、に依存する可能性があります)。それらが呼び出されたとき) またはバージョン チェック時に。新しい iOS 8 の動作が必要な場合もありますが、iOS のすべてのバージョンで安定する必要がある場合は、これで問題ありません。

+(CGSize)screenSizeOrientationIndependent {
     CGSize screenSize = [UIScreen mainScreen].bounds.size;
     return CGSizeMake(MIN(screenSize.width, screenSize.height), MAX(screenSize.width, screenSize.height));
}
于 2014-09-23T18:48:51.843 に答える
11

this question に関連して、私の問題を解決しました。ここでは、画面の幅と高さの計算に使用する 2 つの定義を示します。

#define SCREEN_WIDTH (IOS_VERSION_LOWER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height) : [[UIScreen mainScreen] bounds].size.width)

#define SCREEN_HEIGHT (IOS_VERSION_LOWER_THAN_8 ? (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width) : [[UIScreen mainScreen] bounds].size.height)

#define IOS_VERSION_LOWER_THAN_8 (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)

iOS 7 と iOS 8 の両方をサポートしている場合、これがこの問題の最善の解決策です。

于 2014-10-18T13:52:05.813 に答える
9

使用できますnativeBounds(向きに依存しません)

ネイティブバウンド

物理画面の外接する四角形 (ピクセル単位)。(読み取り専用)

宣言 SWIFT

  var nativeBounds: CGRect { get }

この四角形は、縦向きのデバイスに基づいています。この値は、デバイスが回転しても変化しません。

デバイスの高さの検出:

if UIScreen.mainScreen().nativeBounds.height == 960.0 {

}

デバイスの幅の検出:

if UIScreen.mainScreen().nativeBounds.width == 640.0 {

}
于 2015-01-04T00:20:59.930 に答える
8

これは iOS 8 SDK のバグではありません。彼らは、インターフェースの向きに依存する境界を作りました。その事実への参照またはドキュメントに関する質問によると、WWDC 2014View Controller Advancements in iOS 8の 214 セッションを視聴することを強くお勧めします。最も興味深い部分 (あなたの疑問によると) は、50:45 から始まる部分です。Screen Coordinates

于 2014-08-05T13:41:25.787 に答える
4

私の解決策は、MaxK と hfossli の組み合わせです。UIScreen の Category でこのメソッドを作成しましたが、バージョン チェックはありません (これは悪い習慣です)。

//Always return the iOS8 way - i.e. height is the real orientation dependent height
+ (CGRect)screenBoundsOrientationDependent {
    UIScreen *screen = [UIScreen mainScreen];
    CGRect screenRect;
    if (![screen respondsToSelector:@selector(fixedCoordinateSpace)] && UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
        screenRect = CGRectMake(screen.bounds.origin.x, screen.bounds.origin.y, screen.bounds.size.height, screen.bounds.size.width);
    } else {
        screenRect = screen.bounds;
    }

    return screenRect;
}
于 2014-10-14T21:09:44.753 に答える
3

以下のメソッドを使用して、iOS のバージョンに関係なく、特定の向きの画面境界を見つけることができます。このメソッドは、デバイスの画面サイズに基づいて境界を返し、iOS のバージョンに関係なく同じ CGRect 値を返します。

- (CGRect)boundsForOrientation:(UIInterfaceOrientation)orientation {

    CGFloat width   = [[UIScreen mainScreen] bounds].size.width;
    CGFloat height  = [[UIScreen mainScreen] bounds].size.height;

    CGRect bounds = CGRectZero;

    if (UIInterfaceOrientationIsLandscape(orientation)) {
        bounds.size = CGSizeMake(MAX(width, height), MIN(width, height));
    } else {
        bounds.size = CGSizeMake(MIN(width, height), MAX(width, height));
    }

    return bounds;
}

// For the below example, bounds will have the same value if you run the code on iOS 8.x or below versions.
CGRect bounds = [self boundsForOrientation:UIInterfaceOrientationPortrait]; 
于 2014-11-11T06:17:26.310 に答える
3

iOS8 の下で iOS7 と同じ動作を維持する簡単なヘルパー関数が必要でした。これにより、[[UIScreen mainScreen] bounds]呼び出しを交換し、他のコードに触れないようにすることができました...

+ (CGRect)iOS7StyleScreenBounds {
    CGRect bounds = [UIScreen mainScreen].bounds;
    if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) && UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
        bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
    }
        return bounds;
}
于 2014-10-08T05:32:07.723 に答える
1

私の問題は、マイナスになっているUIWindowsフレームに関連していました。そのため、 MyViewController -(NSUInteger)supportedInterfaceOrientations Method で以下のようにコードを作成しました

[[UIApplication sharedApplication] setStatusBarHidden:NO];

[self.view setFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];

[appDel.window setFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];

そして、私はそれを試してみてください。

于 2015-01-29T13:17:53.093 に答える
1

上記で回答した優れた cbartel 関数の迅速なバージョンを追加するだけです。

func screenSize() -> CGSize {
    let screenSize = UIScreen.mainScreen().bounds.size
    if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) && UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation) {
        return CGSizeMake(screenSize.height, screenSize.width)
    }
    return screenSize
}
于 2015-01-03T22:11:43.510 に答える
0

私が注意したことの 1 つは、Info.plist でサポートされているインターフェイスの向きの順序が重要であるということです。私のアプリ(コードで向きを変える)でこの質問の問題が発生しましたが、デフォルトの向きが縦であることをどこにも指定しませんでした。

いずれにせよ、デフォルトの向き縦だと思いました。

Info.plist で itens を再配置し、Portrait を最初に配置すると、期待どおりの動作が復元されました。

于 2014-09-26T19:35:42.950 に答える
0

これにより、 iOS7iOS8の両方で正しいデバイスが得られます。

#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define IS_PORTRAIT         UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)

+ (BOOL)isIPHONE4{

// < iOS 8.0
if(SYSTEM_VERSION_LESS_THAN(@"8.0")){

        if ([self getDeviceWidth] == 320.0 && [self getDeviceHeight] == 480.0) {
            return YES;
        } else {
            return NO;
        }

// >= iOS 8.0
}else{

    if(IS_PORTRAIT){

        if ([self getDeviceWidth] == 320.0 && [self getDeviceHeight] == 480.0) {
            return YES;
        } else {
            return NO;
        }

    }else{

        if ([self getDeviceWidth] == 480.0 && [self getDeviceHeight] == 320.0) {
            return YES;
        } else {
            return NO;
        }

    }

}


}

+ (BOOL)isIPHONE5{


// < iOS 8.0
if(SYSTEM_VERSION_LESS_THAN(@"8.0")){

    if ([self getDeviceWidth] == 320.0 && [self getDeviceHeight] == 568.0) {
        return YES;
    } else {
        return NO;
    }

    // >= iOS 8.0
}else{

    if(IS_PORTRAIT){

        if ([self getDeviceWidth] == 320.0 && [self getDeviceHeight] == 568.0) {
            return YES;
        } else {
            return NO;
        }

    }else{

        if ([self getDeviceWidth] == 568.0 && [self getDeviceHeight] == 320.0) {
            return YES;
        } else {
            return NO;
        }

    }

}

}

+ (BOOL)isIPHONE6{

// < iOS 8.0
if(SYSTEM_VERSION_LESS_THAN(@"8.0")){

    if ([self getDeviceWidth] == 375.0 && [self getDeviceHeight] == 667.0) {
        return YES;
    } else {
        return NO;
    }

    // >= iOS 8.0
}else{

    if(IS_PORTRAIT){

        if ([self getDeviceWidth] == 375.0 && [self getDeviceHeight] == 667.0) {
            return YES;
        } else {
            return NO;
        }

    }else{

        if ([self getDeviceWidth] == 667.0 && [self getDeviceHeight] == 375.0) {
            return YES;
        } else {
            return NO;
        }

    }

}


}
+ (BOOL)isIPHONE6Plus{


// < iOS 8.0
if(SYSTEM_VERSION_LESS_THAN(@"8.0")){

    if ([self getDeviceWidth] == 414.0 && [self getDeviceHeight] == 736.0) {
        return YES;
    } else {
        return NO;
    }

    // >= iOS 8.0
}else{

    if(IS_PORTRAIT){

        if ([self getDeviceWidth] == 414.0 && [self getDeviceHeight] == 736.0) {
            return YES;
        } else {
            return NO;
        }

    }else{

        if ([self getDeviceWidth] == 736.0 && [self getDeviceHeight] == 414.0) {
            return YES;
        } else {
            return NO;
        }

    }

}


}

+ (CGFloat)getDeviceHeight{

//NSLog(@"Device width: %f",[UIScreen mainScreen].bounds.size.height);
return [UIScreen mainScreen].bounds.size.height;
}
+ (CGFloat)getDeviceWidth{

//NSLog(@"Device width: %f",[UIScreen mainScreen].bounds.size.height);
return [UIScreen mainScreen].bounds.size.width;
}

//さらにデバイスを追加することもできます(つまりiPad)。

于 2015-03-23T09:33:58.597 に答える