programing

[UISCreen mainScreen]입니다.iOS8에서 방향 의존적이 되는 bounds.size?

sourcejob 2023. 7. 13. 20:50
반응형

[UISCreen mainScreen]입니다.iOS8에서 방향 의존적이 되는 bounds.size?

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의 일시적인 버그입니까?

네, iOS8에서는 버그가 아닌 방향 의존적입니다.자세한 내용은 WWDC 2014의 세션 214를 참조하십시오. "View Controller Advanced in iOS 8"

프레젠테이션에서 인용한 내용:

UIS 화면은 이제 인터페이스 지향적입니다.

  • [UIS 화면 경계] 인터페이스 지향
  • [UIScreen applicationFrame] 인터페이스 지향
  • 상태 표시줄 프레임 알림은 인터페이스 지향적입니다.
  • 키보드 프레임 알림이 인터페이스 지향적임

네, 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;
}

네, 실제로 화면 크기는 이제 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;
}

네, 이제 방향에 따라 다릅니다.

화면 크기를 위의 일부 답변보다 방향 독립적인 방법으로 가져오는 다음 방법을 선호합니다. 화면 크기가 더 단순하고 방향 코드(상태는 호출 시간에 따라 달라질 수 있음)나 버전 확인에 의존하지 않기 때문입니다.당신은 새로운 iOS 8 동작을 원할 수도 있지만, 만약 당신이 iOS의 모든 버전에서 안정적이어야 한다면 이것은 작동할 것입니다.

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

문제를 해결한 이 질문과 관련하여 화면 너비 및 높이 계산에 사용하는 두 가지 정의가 있습니다.

#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을 모두 지원하는 경우 이 문제에 가장 적합한 솔루션입니다.

사용할 수 있습니다.nativeBounds방향 비의존)방

네이티브 바운드

픽셀 단위로 측정된 실제 화면의 경계 사각형(읽기 전용)

선언 SWIFT

  var nativeBounds: CGRect { get }

이 직사각형은 세로 방향의 장치를 기준으로 합니다.이 값은 장치가 회전할 때 변경되지 않습니다.

장치 높이 감지:

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

}

장치 너비 감지:

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

}

iOS 8 SDK의 버그가 아닙니다.경계 인터페이스 방향에 의존하도록 했습니다.그 사실에 대한 참조나 문서에 대한 당신의 질문에 따르면, 저는 당신이 보기를 강력히 추천할 것입니다.View Controller Advancements in iOS 8WWDC 2014의 214 세션입니다.(당신의 의심에 따라) 가장 흥미로운 부분은.Screen Coordinates45분 45초에 합니다.

네, iOS8에서는 방향에 따라 다릅니다.

SDK 및 OS 버전에서 iOS 8 방식으로 경계를 일관되게 읽을 수 있는 방법은 다음과 같습니다.

#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

저는 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;
}

나의 해결책은 MaxK와 hfossli의 조합입니다.UIS 화면의 범주에서 이 방법을 만들었지만 버전 검사가 없습니다(나쁜 관행).

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

아래 방법은 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]; 

iOS 8 이상

화면 크기를 포인트 단위로 알고 싶은 사람들을 위한 솔루션(3.5인치 화면은 320x480포인트, 4.0인치 화면은 320x568포인트 등)은 다음과 같습니다.

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

그것이 제가 정확한 정류를 계산하기 위해 사용한 것입니다.

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

우수한 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
}

나의 문제는 마이너스로 들어가는 UI 윈도우 프레임과 관련이 있었습니다.그래서 MyViewController의 아래와 같은 코드를 만들었습니다 - (NSUInteger)가 지원됩니다.인터페이스 방향 방법

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

제가 할 수 있는 일입니다.

메인 화면 경계에서 min/max를 사용하여 iOS 버전을 확인하지 않는 약간 수정된 Mnemia의 솔루션을 사용했습니다.
나는 필요했습니다.CGRect그래서 얻은CGRect 및 된 화면에서size.width=min(w,h),size.height=max(w,h)그리고 OS에 의존하지 않는 GET를 호출했습니다.CGRect두하며, 서 나는 내코의두위기며능하서, 나화크얻습다니기를면는여기서드에 대한 화면 .OpenGL촉감 등수정하기 전에 IOS 8.x에서 가로 모드 디스플레이 위치의 두 가지 문제가 있었습니다.OpenGL전체 화면의 1/4이 왼쪽 하단 부분에 표시됩니다.그리고 두 번째 터치는 잘못된 값을 반환했습니다.두 문제 모두 설명대로 해결되었습니다.감사합니다!

제가 주목한 한 가지는 Info.plist에서 지원되는 인터페이스 방향의 순서가 중요하다는 것입니다.(코드에서 방향을 지정하는) 앱에서 이 질문에 대한 문제가 발생했지만, 기본 방향을 세로로 지정하지 않았습니다.

기본 방향은 어쨌든 세로 방향이라고 생각했습니다.

Info.plist에서 항목을 재정렬하고 Priotal을 먼저 지정하여 예상 동작을 복원했습니다.

이것은 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)를 추가할 수도 있습니다.

언급URL : https://stackoverflow.com/questions/24150359/is-uiscreen-mainscreen-bounds-size-becoming-orientation-dependent-in-ios8

반응형