2014-11-17 2 views
2

레벨이 인 UIWindow를 추가하려고합니다. 그것은 ipad에 세로 모드에서 완벽하게 작동하지만 장치를 뒤집어서 엉망으로 만듭니다.iOS 8/7 UIWindowLevelStatusBar가있는 UIWindow 회전 문제

iOS 7.x에서 모든 회전은 거꾸로되어있는 경우를 제외하고는 괜찮습니다. iOS 8.x에서는 세로 모드 만 좋으며 다른 모든 방향은 엉망입니다. 어떤 생각을 어떻게 해결할 수 있을까요? 그런 다음

// Rotation Notifications 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeOrientation:) name:UIDeviceOrientationDidChangeNotification object:nil]; 

self.baseT = self.transform; 

방법 자체 :

- (void)didChangeOrientation:(NSNotification *)n 
{ 

    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; 

    switch (orientation) { 
     case UIInterfaceOrientationPortrait: 
      self.transform = CGAffineTransformRotate(self.baseT, 0); 
      break; 
     case UIInterfaceOrientationPortraitUpsideDown: 
      self.transform = CGAffineTransformRotate(self.baseT, M_PI); 
      break; 
//  Home button on left 
     case UIInterfaceOrientationLandscapeLeft: 
      self.transform = CGAffineTransformRotate(self.baseT, -M_PI_2); 
      break; 
     case UIInterfaceOrientationLandscapeRight: 
      self.transform = CGAffineTransformRotate(self.baseT, M_PI_2); 
      break; 
     default: 
      self.transform = CGAffineTransformMakeRotation(0); 
      break; 
    } 
} 

구현에 따라, 당신은 또한 보장 할 수 있습니다 당신의 UIWindow 하위 클래스 'init 메소드에서

CGRect frame = [UIApplication sharedApplication].statusBarFrame; 
self.statusWindow = [[UIWindow alloc] initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, 20)]; 

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; 
CGRect frame = [UIApplication sharedApplication].statusBarFrame; 
CGAffineTransform test = [self transformForOrientation:orientation]; 

[self.statusWindow setWindowLevel:UIWindowLevelStatusBar]; 
[self.statusWindow setHidden:NO]; 


- (CGAffineTransform)transformForOrientation:(UIInterfaceOrientation)orientation 
{ 
switch (orientation) 
{ 
    case UIInterfaceOrientationLandscapeLeft: 
     return CGAffineTransformMakeRotation(-DEGREES_TO_RADIANS(90.0f)); 

    case UIInterfaceOrientationLandscapeRight: 
     return CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(90.0f)); 

    case UIInterfaceOrientationPortraitUpsideDown: 
     return CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(180.0f)); 

    case UIInterfaceOrientationPortrait: 
    default: 
     return CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(0.0f)); 
} 
} 
+0

이것은 방향 지원을 다루는 매우 무작위적인 방법입니다. 'rootWindow'는'rootViewController' 속성을 올바로 설정하는 한 모든 것을 처리 할 수 ​​있고 처리 할 수 ​​있기 때문에 아무것도 변형하지 말아야합니다. – holex

+0

코드에서 뭔가가 누락되어 있으면 statusWindow와 관련된 모든 코드가 표시됩니다. 설명을 위해 – Sven

+0

이 코드는 상태 표시 줄 위에 또 다른 uiwindow를 설정합니다. 그래서 rootviewcontroller가 없다. 내가 변환하지 않으면 uiwindow가 세로 모드로 유지되고 iOS 7이나 iOS 8에서도 회전하지 않으므로 수동으로 회전해야합니다. 더 나은 방법을 알고 있다면 공유하십시오. –

답변

0

이 알림을 관찰 프레임이 변경되지 않습니다. 또한 Class 'dealloc 메소드에서 알림 수신을 중단하십시오.

+0

덕분에 나는 그것을 시도하고 알려 드리겠습니다. –

+0

회전이 작동하지만 uiwindow가 화면 방향에 따라 올바르게 배치되고 크기가 조정되지 않습니다. 어쨌든 노력에 감사드립니다. –

0

@ dezinezync의 답변에 대한 수정 사항 :보기 컨트롤러의 willRotateToInterfaceOrientation 메서드에 넣을 때 회전을 수행하면 더 잘 작동합니다. 이렇게하면 회전은 앱의 빌드 설정에있는 일반 -> 배포 정보 섹션에 지정된 지원되는 방향 중 하나로 회전하는 경우에만 적용됩니다. 추가 보너스로, 순환 애니메이션의 지속 시간에 액세스 할 수 있습니다. 보기 컨트롤러에서 모달 창에 대한 참조가 있는지 확인하십시오.

UIDeviceOrientationDidChangeNotification 알림은 지원되는 방향에 관계없이 화면 방향이 변경 될 때마다 발생합니다. 이로 인해 원치 않는 행동이 발생할 수 있습니다.

다음은 예입니다 :

UIWindow *modalWindow; 

// Initialize your modal window somewhere in your code 
// ... 

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{ 
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; 

    // Make sure the modalWindow exists 
    if (modalWindow != nil) 
    { 
     // Animate the modal window's rotation 
     [UIView animateWithDuration:duration animations:^{ 
      [self rotateModal:modalWindow]; 
     }]; 
    } 
} 

- (void)rotateModal:(UIWindow*)window 
{ 

    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; 

    switch (orientation) { 
     case UIInterfaceOrientationPortrait: 
      window.transform = CGAffineTransformRotate(self.baseT, 0); 
      break; 
     case UIInterfaceOrientationPortraitUpsideDown: 
      window.transform = CGAffineTransformRotate(self.baseT, M_PI); 
      break; 
//  Home button on left 
     case UIInterfaceOrientationLandscapeLeft: 
      window.transform = CGAffineTransformRotate(self.baseT, -M_PI_2); 
      break; 
     case UIInterfaceOrientationLandscapeRight: 
      window.transform = CGAffineTransformRotate(self.baseT, M_PI_2); 
      break; 
     default: 
      window.transform = CGAffineTransformMakeRotation(0); 
      break; 
    } 
} 

난 그냥 풍경 전용 응용 프로그램에서이 같은 일을했고, 나는 마침내는 willRotateToInterfaceOrientation 방법에 이르기까지 모든 이동하여 제대로 작동 얻었다. iOS8의에 대한

0

솔루션 (물론 위에서 보여 같은 변환이 필요) :

UIScreen *screen = [UIScreen mainScreen]; 
CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame; 
if ([screen respondsToSelector:@selector(fixedCoordinateSpace)]) 
{ 
    [self setFrame:[screen.coordinateSpace convertRect:statusBarFrame toCoordinateSpace:screen.fixedCoordinateSpace]]; 
} 

는 iOS9 베타 작동하지 않습니다하지만.