2010-02-11 5 views
26

잘 작동하는 UITabBar 기반 응용 프로그램이 있습니다. 특정 상황에서 대신 다른 UIViewController 보여 오전. 이제 어떤 버그가 생겼 는가? 테스트 펜촉 (!) 만 제대로 표시되도록 프레임을 조정해야한다는 것입니다. 그렇지 않으면보기가 상태 표시 줄 아래에 있습니다.UIWindow의 오프셋 addSubview

- (void)applicationDidFinishLaunching:(UIApplication *)application 
{ 
    if (condition) { 

     UIViewController *vc = [[UIViewController alloc] initWithNibName:@"Test" bundle:nil]; 

     // FIXME this should NOT be required 
     CGRect r = vc.view.frame; 
     r.origin.y += 20; 
     vc.view.frame = r; 

     [window addSubview:vc.view]; 
     [window makeKeyAndVisible]; 
     return; 
    } 

    [window addSubview:tabViewController.view]; 
    [window makeKeyAndVisible]; 
} 

아마도 Test nib에 문제가 있습니까? 될 수 없다. 테스트 펜촉은 깨끗한 새 프로젝트에서 원하는대로 작동합니다. 새로운 깨끗한 펜촉도 같은 증상을 보입니다. 그래서 MainWindow 펜촉으로 뭔가 이상해야합니다. 맞습니까? 그러나 UITabBarController 잘 표시됩니다.

나는 조금 혼란스럽고 여기에 아이디어가 부족합니다. 이 문제를 어떻게 추적 할 것인가?

답변

76

창은 항상 상태 표시 줄을 underlaps 때문에 복잡 할 수 있습니다 UIWindow에 루트 뷰를 추가. 따라서 루트보기의 프레임은 [[UIScreen mainScreen] applicationFrame]으로 재설정해야 상태 표시 줄에 언더 랩핑이 발생하지 않습니다. UIViewController가 우리를 위해 프레임을 수정하기 때문에 일반적으로 걱정할 필요가 없습니다. 여기 거래는 다음과 같습니다 당신이 당신의 뷰 컨트롤러 과 같은 NIB에서의 뷰를 작성하는 경우

  • 하고 둥지보기보기 컨트롤러 아래에, 그것은 것이다가 자동으로 뷰의 프레임을 조정합니다.
  • 당신이 당신의 뷰 컨트롤러와 같은 NIB에서 의 뷰를 작성하는 경우,하지만 당신이 그것을 중첩보다는 컨트롤러의 보기 콘센트를 통해보기 컨트롤러에 뷰를 연결 , 컨트롤러가 조정되지 않습니다 보기의 프레임이 자동으로 표시됩니다. 하나 NIB에서보기 컨트롤러를 만들고, 당신이 IB에서보기 컨트롤러의 "NIB 이름"속성을 설정하여 분리 된 NIB에 정의 된 뷰에 연결하면
  • , 그것은 은 자동으로 뷰의 프레임을 조정합니다 의 경우에만 "NIB에서 크기 조정보기"를 선택해야합니다. 당신이 전화 -initWithNibName하여 뷰 컨트롤러 작성하는 경우
  • 은 : 번들 :, 그것은 자동으로 뷰의 프레임을 조정하지 것입니다.
  • UITabBarController는 뷰를 윈도우의 루트보기로 추가 할 것을 기대하므로 항상 자동으로 응용 프로그램 프레임과 일치하도록 자체 뷰의 프레임을 조정합니다. (혹시 윈도우 이외의 하위 뷰 같은 UITabBarController가의보기를 추가하면 결과적으로 당신은 이상한 20 픽셀 차이를 알 수 있습니다.)

을 나는 애플이 그 -initWithNibName 생각 같아요 번들 : 것 없습니다 일반적으로 윈도우의 루트보기를 만드는 데 사용되므로 프레임의 경우에는 프레임을 조정하지 않습니다.당신이했던 것처럼 수동으로 크기를 조정하면 괜찮 및 View Controller Programming Guide for iPhone OS에 추천 사실이지만, 상태 표시 줄이 아니기 때문에 정말 [[UIScreen mainScreen] applicationFrame]를 사용해야합니다 항상 20 픽셀 높이 (예를 들어, 당신이 전화 통화에있을 때이 키의 .) 이상 무슨 말을했는지 그냥 두 번째로

+3

만약 내가 할 수있는 두번 upvote 줄 : –

+1

iOS 개발에서 가장 성가신 일반적인 이상한 중 하나에 대한 명확한 대답. 5 별, 10/10, 다시 재생할 것입니다 –

+0

전체 답변을 읽을 수는 없지만 [[UIScreen mainScreen] applicationFrame] –

0

UITabBarController은 IB 콘센트이므로 applicationDidFinishLaunching:이 호출 될 때 이미 초기화되었습니다. 다음을 시도해보십시오 당신의 뷰 컨트롤러의 인스턴스 후, 수행

[vc setWantsFullScreenLayout:YES]; 
+0

화면의 맨 아래에있는 20 픽셀 (보기의 배경색이 아닌 흰색)이 사라지고 전체 영역이 덮여 있습니다. 그러나 UI 컨트롤은 여전히 ​​20 픽셀 위쪽에 너무 가깝습니다. 그래서 이것은 320x460에서 320x480으로보기의 크기를 조정한다고 생각합니다. 그 기원은 여전히 ​​틀리다. 그리고이 모든 후에는 단지 해결 방법이 될 것입니다. 나는 이것을위한 원인을 찾고 싶다. – tcurdt

0

: 여기 내가 사용했던 코드입니다 :

#define MAIN_SCREEN_OFFSET_PIXELS  20 

- (void) pushDownViewOnMainScreen { 
    CGRect r = [[UIScreen mainScreen] applicationFrame]; 
    r.origin.y -= MAIN_SCREEN_OFFSET_PIXELS; 

    self.view.frame = r; 
} 


- (void) viewDidLoad { 
    [self pushDownViewOnMainScreen]; 

    // ... 
} 
4

이 나중에 훨씬 간단하고도 작업 (아이폰 OS 4.0)

MyRootViewController *vc = [[MyRootViewController alloc] init];  
[window setRootViewController:vc]; 
[vc release]; 

가 - setRootViewContro ller는 컨트롤러의 뷰를 창에 자동으로 추가하므로 걱정할 필요가 없습니다. 이 건물은 효과적으로 UIWindow에 개체의 소유권을 손 그래서 창에 할당 후 해제 (비 원자, 유지)하고 윈도우가 해제 될 때 발표 (결과적으로 할당 해제)됩니다. 당신은 물론 인스턴스 변수를 만들고에 대한 참조를 유지하고 다른 응용 프로그램 위임 방법에 그것으로 물건을 수행하려는 경우 -dealloc에서 해제 할 수있다. 위의 방법은 자동으로 정리 작업을 처리하므로 선호합니다. 당신은, 당신은 즉시 하위 뷰 같은 다른보기로 의견을 추가하거나 모달 뷰 컨트롤러보기를 제시 한 후 뷰 컨트롤러를 해제 할 수 있습니다 모르는 경우

. 뷰가 제거되거나 뷰 스택에서 튀어 나올 때마다 해당 컨트롤러가 해제됩니다. 당신은 initWithNibName, 그냥 ... ALLOC] 초기화]를 사용할 필요가 없습니다

; 할 것이다.

+0

키워드에 매우 만족합니다. 펜촉에서로드하는 경우 initWithNibName을 사용해야합니다. , ofc ... – fnf