it-swarm.com.de

Wird [UIScreen mainScreen] .bounds.size in iOS8 orientierungsabhängig?

Ich habe den folgenden Code in iOS 7 und iOS 8 ausgeführt:

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);

Folgendes ist das Ergebnis von iOS 8:

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

Im Vergleich zum Ergebnis in iOS 7:

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

Gibt es eine Dokumentation, die diese Änderung spezifiziert? Oder ist es ein vorübergehender Fehler in iOS 8-APIs?

183
lwxted

Ja, es ist orientierungsabhängig in iOS8, kein Fehler. Weitere Informationen finden Sie in Sitzung 214 von WWDC 2014: "Controller-Verbesserungen in iOS 8 anzeigen"

Zitat aus der Präsentation:

UIScreen ist jetzt schnittstellenorientiert:

  • [UIScreen-Grenzen] jetzt schnittstellenorientiert
  • [UIScreen applicationFrame] jetzt schnittstellenorientiert
  • Rahmenbenachrichtigungen in der Statusleiste sind schnittstellenorientiert
  • Benachrichtigungen zu Tastaturrahmen sind schnittstellenorientiert
173
vhristoskov

Ja, es ist orientierungsabhängig in iOS8.

Ich habe eine Util-Methode geschrieben, um dieses Problem für Apps zu beheben, die ältere Versionen des Betriebssystems unterstützen müssen.

+ (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;
}
59
cbartel

Ja, in der Tat, die Bildschirmgröße ist jetzt abhängig von der Ausrichtung in iOS 8. Manchmal ist es jedoch erwünscht, eine Größe festzulegen, die auf die Ausrichtung im Hochformat festgelegt ist. Hier ist, wie ich es mache.

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

    if ([screen respondsToSelector:@selector(fixedCoordinateSpace)]) {
                    return [screen.coordinateSpace convertRect:screen.bounds toCoordinateSpace:screen.fixedCoordinateSpace];
    } 
    return screen.bounds;
}
34
MaxK

Ja, es hängt jetzt von der Orientierung ab.

Ich bevorzuge die unten beschriebene Methode, um die Bildschirmgröße orientierungsunabhängig zu bestimmen, gegenüber einigen der obigen Antworten, da sie einfacher ist und von keinem der Orientierungscodes abhängt (deren Status von den folgenden abhängig sein kann) Uhrzeit, zu der sie aufgerufen werden) oder bei der Versionsüberprüfung. Möglicherweise möchten Sie das neue iOS 8-Verhalten, dies funktioniert jedoch, wenn es auf allen iOS-Versionen stabil sein soll.

+(CGSize)screenSizeOrientationIndependent {
     CGSize screenSize = [UIScreen mainScreen].bounds.size;
     return CGSizeMake(MIN(screenSize.width, screenSize.height), MAX(screenSize.width, screenSize.height));
}
32
mnemia

Bezogen auf diese Frage, da sie mein Problem löste, benutze ich hier zwei Definitionen für die Berechnung der Bildschirmbreite und -höhe:

#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)

Wenn Sie sowohl iOS 7 als auch iOS 8 unterstützen, ist dies die beste Lösung für dieses Problem.

11
Antoine

Sie können nativeBounds verwenden (orientierungsunabhängig)

nativeBounds

Das Begrenzungsrechteck des physischen Bildschirms, gemessen in Pixel. (schreibgeschützt)

Erklärung Swift

  var nativeBounds: CGRect { get }

Dieses Rechteck basiert auf dem Gerät im Hochformat. Dieser Wert ändert sich nicht, wenn sich das Gerät dreht.

Erkennen der Gerätehöhe:

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

}

Erkennen der Gerätebreite:

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

}
9
Leo Dabus

Es ist kein Fehler in iOS 8 SDK. Sie haben die Ausrichtung der Grenzflächen abhängig gemacht. Entsprechend Ihrer Frage zu einem Verweis oder einer Dokumentation auf diese Tatsache werde ich Ihnen wärmstens empfehlen, View Controller Advancements in iOS 8 Es ist 214 Sitzung von WWDC 2014 . Der interessanteste Teil (nach Ihren Zweifeln) ist Screen Coordinates das beginnt um 50:45.

8
Julian Król

Ja, es ist orientierungsabhängig in iOS8.

Hier erfahren Sie, wie Sie auf konsistente Weise Grenzen auf iOS 8-Art und Weise über SDKs und Betriebssystemversionen hinweg auslesen können.

#ifndef NSFoundationVersionNumber_iOS_7_1
# define NSFoundationVersionNumber_iOS_7_1 1047.25
#endif

@implementation UIScreen (Legacy)

// iOS 8 way of returning bounds for all SDK's and OS-versions
- (CGRect)boundsRotatedWithStatusBar
{
    static BOOL isNotRotatedBySystem;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        BOOL OSIsBelowIOS8 = [[[UIDevice currentDevice] systemVersion] floatValue] < 8.0;
        BOOL SDKIsBelowIOS8 = floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1;
        isNotRotatedBySystem = OSIsBelowIOS8 || SDKIsBelowIOS8;
    });

    BOOL needsToRotate = isNotRotatedBySystem && UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
    if(needsToRotate)
    {
        CGRect screenBounds = [self bounds];
        CGRect bounds = screenBounds;
        bounds.size.width = screenBounds.size.height;
        bounds.size.height = screenBounds.size.width;
        return bounds;
    }
    else
    {
        return [self bounds];
    }
}

@end
5
hfossli

Meine Lösung ist eine Kombination aus MaxK's und hfossli. Ich habe diese Methode auf einer UIScreen-Kategorie erstellt und es gibt keine Versionsüberprüfung (was eine schlechte Praxis ist):

//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;
}
4
Uzair Khan

Mit der folgenden Methode können Sie die Bildschirmgrenzen für eine bestimmte Ausrichtung unabhängig von der iOS-Version ermitteln. Diese Methode gibt die Grenzen basierend auf der Bildschirmgröße des Geräts zurück und gibt den gleichen CGRect-Wert unabhängig von der iOS-Version.

- (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]; 
3
user4226071

Ich brauchte eine schnelle Hilfefunktion, die das gleiche Verhalten wie iOS7 unter iOS8 beibehielt. Dadurch konnte ich mein [[UIScreen mainScreen] bounds] ruft an und berührt keinen anderen Code ...

+ (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;
}
3
Joe Booth

So habe ich das richtige Rect berechnet:

UIScreen* const mainScreen = [UIScreen mainScreen];
CGRect rect = [mainScreen bounds];
#ifdef __IPHONE_8_0
if ([mainScreen respondsToSelector:@selector(coordinateSpace)])
{
    if ([mainScreen respondsToSelector:@selector(fixedCoordinateSpace)])
    {
        id tmpCoordSpace = [mainScreen coordinateSpace];
        id tmpFixedCoordSpace = [mainScreen fixedCoordinateSpace];

        if ([tmpCoordSpace respondsToSelector:@selector(convertRect:toCoordinateSpace:)])
        {
            rect = [tmpCoordSpace convertRect:rect toCoordinateSpace: tmpFixedCoordSpace];
        }
    }
}
#endif
1
hhamm

Mein Problem hatte mit dem UIWindows-Frame zu tun, der im Minusbereich lag. So machte der Code wie folgt in MyViewController - (NSUInteger) supportedInterfaceOrientations-Methode

[[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)];

Und seine Arbeit für mich versuchen Sie es.

1
Hardik Mamtora

Fügen Sie einfach die Swift Version einer ausgezeichneten Cbartel-Funktion hinzu, die oben beantwortet wurde.

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
}
1
Martin Koles

Verwendete eine leicht modifizierte Mnemia-Lösung, die keine iOS-Versionsprüfung durch Verwenden von Min/Max an den Grenzen des Hauptbildschirms durchführt.
Ich brauchte ein CGRect, habe also CGRect vom Hauptbildschirm entfernt und size.width=min(w,h), size.height=max(w,h) geändert. Dann habe ich die betriebssystemunabhängige Funktion get CGRect an zwei Stellen in meinem Code aufgerufen, wo ich die Bildschirmgröße für OpenGL, Berührungen usw. erhalte. Vor der Fehlerbehebung hatte ich 2 Probleme - on IOS 8.x im Querformat war die Anzeigeposition der OpenGL -Ansicht falsch: 1/4 des Vollbilds im linken unteren Teil. Bei der zweiten Berührung wurden ungültige Werte zurückgegeben. Beide Probleme wurden wie erläutert behoben. Vielen Dank!

0
NoAngel

Eine Sache, die ich bemerkt habe, ist die Reihenfolge der unterstützten Interface-Orientierungen in Info.plist. Ich habe das Problem dieser Frage mit meiner App (die die Ausrichtung im Code ausführt), aber ich habe nirgends angegeben, dass die Standardausrichtung Hochformat ist.

Ich dachte, dass die Standardausrichtung war Hochformat auf jeden Fall.

Durch Neuanordnen von Elementen in Info.plist wurde das erwartete Verhalten wiederhergestellt, wobei Portrait an erster Stelle stand.

0
epx

Dies gibt das richtige Gerät in iOS7 und iOS8,

#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;
}

// Sie können auch weitere Geräte hinzufügen (d. H. IPad).

0
Zaid Pathan

iOS 8 oder höher

Eine Lösung für diejenigen, die die Bildschirmgröße in Punkten ermitteln möchten (3,5-Zoll-Bildschirm hat 320 × 480 Punkte, 4,0-Zoll-Bildschirm hat 320 × 568 Punkte usw.), wäre

- (CGSize)screenSizeInPoints
{
    CGFloat width = [[UIScreen mainScreen] bounds].size.width;
    CGFloat height = [[UIScreen mainScreen] bounds].size.height;

    if (width > height) {
        return CGSizeMake(height, width);
    }
    else {
        return [[UIScreen mainScreen] bounds].size;
    }
}
0
tesla