내 응용 프로그램의 현재 높이와 너비를 프로그래밍 방식으로 결정하려고합니다. 나는 이것을 사용한다 :
CGRect screenRect = [[UIScreen mainScreen] bounds];
그러나 이것은 장치가 세로 방향이든 가로 방향이든 상관없이 너비 320과 높이 480을 산출합니다. 메인 화면 의 현재 너비와 높이 (즉, 장치 방향에 따라 다름)를 어떻게 확인할 수 있습니까?
내 응용 프로그램의 현재 높이와 너비를 프로그래밍 방식으로 결정하려고합니다. 나는 이것을 사용한다 :
CGRect screenRect = [[UIScreen mainScreen] bounds];
그러나 이것은 장치가 세로 방향이든 가로 방향이든 상관없이 너비 320과 높이 480을 산출합니다. 메인 화면 의 현재 너비와 높이 (즉, 장치 방향에 따라 다름)를 어떻게 확인할 수 있습니까?
답변:
같은 UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)것을 사용하여 방향을 결정한 다음 그에 따라 치수를 사용할 수 있습니다 .
그러나 UIViewController에서와 같이 방향이 변경되는 동안
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
toInterfaceOrientationUIApplication의 statusBarOrientation은 아직 변경되지 않았기 때문에 ( will이벤트 핸들러 내부에 있기 때문에) 여전히 이전 방향을 가리 키므로 전달 된 방향을 사용하십시오 .
요약
이와 관련된 여러 게시물이 있지만 각각 다음을 수행해야 함을 나타내는 것 같습니다.
[[UIScreen mainScreen] bounds]크기를 얻으려면,연결
작업 코드
나는 보통 여기까지 가지 않지만 당신은 내 관심을 불러 일으켰습니다. 다음 코드가 트릭을 수행해야합니다. UIApplication에 카테고리를 작성했습니다. UIViewController의 .NET Framework에서 호출하는 지정된 방향으로 currentSize 또는 크기를 가져 오는 클래스 메서드를 추가했습니다 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을 빼야했습니다.
도움이 되었기를 바랍니다. :디
다른 생각들
UIWindow의 rootViewController속성을 확인 하여 치수를 가져올 수 있습니다. 나는 과거에 이것을 보았고 회전 변환이 있다고보고하는 것을 제외하고 세로 및 가로 모두에서 동일한 치수를 유사하게보고합니다.
(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController]보기]
<UILayoutContainerView : 0xf7296f0; 프레임 = (0 0; 320480); 변형 = [0, -1, 1, 0, 0, 0]; 자동 크기 조정 = W + H; 레이어 = <CALayer : 0xf729b80 >>
(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController]보기]
<UILayoutContainerView : 0xf7296f0; 프레임 = (0 0; 320480); 자동 크기 조정 = W + H; 레이어 = <CALayer : 0xf729b80 >>
앱이 어떻게 작동하는지 확실하지 않지만 어떤 종류의 탐색 컨트롤러를 사용하지 않는 경우 기본보기 아래에 부모의 최대 높이 / 너비가 있고 부모와 함께 확장 / 축소되는 UIView가있을 수 있습니다. 그런 다음 할 수 [[[[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] subviews] objectAtIndex:0] frame]있습니다.. 한 줄에서 꽤 강렬 해 보이지만 아이디어를 얻습니다.
그러나 ... 요약 아래에서 위의 3 단계를 수행하는 것이 좋습니다. UIWindows를 엉망으로 만들면 UIAlertView가 UIAlertView가 만든 새 UIWindow를 가리 키도록 UIApplication의 키창을 변경하는 것과 같은 이상한 것들을 발견하게 될 것입니다. 누가 알았 겠어? 나는 keyWindow에 의존하는 버그를 발견하고 그것이 그렇게 변경되었음을 발견 한 후에했다!
applicationFrame대신 사용 bounds하면 상태 표시 줄 높이를 뺄 필요가 없습니다.
mainScreen().bounds.size 이후 아이폰 OS 8에서 좌우 방향이되었다
이것은 내 솔루션 코드입니다!이 메소드는 NSObject 클래스의 Categroy에 추가하거나 Top 사용자 정의 UIViewController 클래스를 정의하고 다른 모든 UIViewController가 상속하도록 할 수 있습니다.
-(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 ;
}
참고 , IOS8 이후 UIScreen의 경계 속성에 대한 Apple 문서는 다음 과 같이 말합니다.
토론
이 사각형은 현재 좌표 공간에 지정되며 장치에 적용되는 모든 인터페이스 회전을 고려합니다. 따라서이 속성의 값은 기기가 세로 방향과 가로 방향 사이에서 회전 할 때 변경 될 수 있습니다.
따라서 호환성을 고려하여 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 ;
}
다음은 편리한 매크로입니다.
#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)
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
}];
}
이것은 크기에 대한 정보를 제공하지 않는 사용되지 않는 애니메이션 메소드를 대체합니다.
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
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 ;
}
방향에 따른 크기를 원하고 뷰가있는 경우 다음을 사용할 수 있습니다.
view.bounds.size
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
다음은 방향에 따른 화면 크기를 얻는 신속한 방법입니다.
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
}
다음은 내 프로젝트의 표준 기능으로 포함됩니다.
float msWidth = [[UIScreen mainScreen] bounds].size.width*(IS_RETINA?2.0f:1.0f);
float msHeight = [[UIScreen mainScreen] bounds].size.height*(IS_RETINA?2.0f:1.0f);
if ( UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ) {
os->setWidth(MIN(msWidth, msHeight));
os->setHeight(MAX(msWidth, msHeight));
} else {
os->setWidth(MAX(msWidth, msHeight));
os->setHeight(MIN(msWidth, msHeight));
}
NSLog(@"screen_w %f", os->getWidth());
NSLog(@"screen_h %f", os->getHeight());
그러나 iOS 8.0.2에서는 :
+ (NSUInteger)currentWindowWidth
{
NSInteger width = 0;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
CGSize size = [UIScreen mainScreen].bounds.size;
// if (UIInterfaceOrientationIsLandscape(orientation)) {
// width = size.height;
// } else {
width = size.width;
// }
return width;
}