2014-02-21 4 views
0

장치가 방향을 바꿀 때 UIDeviceOrientationDidChangeNotification이 여러 번 호출 중입니다. 나는 이것이 왜 일어나는 지 또는 어떻게 고쳐야하는지 확신 할 수 없다.UIDeviceOrientationDidChangeNotification multiple be more

내가하려는 것은 scrollview의 contentoffset을 동일하게 유지하는 것입니다. 따라서 사용자가 화면을 회전 할 때 앱이 자신이 있던 페이지를 유지합니다.

이상한 점은 내가 원하는 것처럼 코드가 처음 실행될 때 화면이 회전하는 것입니다. 그러나 그 후에 코드가 여러 번 실행되고 결국 contentoffset이 0으로 설정됩니다.

다음은 내가 가진 것입니다.

- (void)loadView { 

    //some code that sizes itself depending on the current orientation 
    //WILL BE CALLED AFTER EVERY ORIENTATION CHANGE 

} 

- (void)viewDidLoad { 

    //begin generating messages 
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 


    [[NSNotificationCenter defaultCenter] 
     addObserver:self selector:@selector(orientationChanged:) 
     name:UIDeviceOrientationDidChangeNotification 
     object:[UIDevice currentDevice]]; 

    //if is portrait and was landscape 
    if (orientation==1 && temp==2) { 
     int cal = offsetHolder.x/screenframe.size.height; 
     offsetHolder.x = cal * screenframe.size.width; 
     ScrollView.contentOffset = offsetHolder; 
    } 

    //if is landscape and was portrait 
    if (orientation==2 && temp==1) { 
     int cal = offsetHolder.x/screenframe.size.width; 
     offsetHolder.x = cal * screenframe.size.height; 
     ScrollView.contentOffset = offsetHolder; 
    } 


} 

방향 변경시 'int orientation'값을 변경 한 다음 loadview를 호출하여보기의 크기를 변경하십시오. 그런 다음 적절한 contentoffset에게

- (void) orientationChanged:(NSNotification *)note { 

    CGRect screenframe = [[UIScreen mainScreen] bounds]; 

    //holding the current offset 
    offsetHolder = ScrollView.contentOffset; 

    if ([[UIDevice currentDevice] orientation] == 1 || [[UIDevice currentDevice] orientation] == 0 || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) { 
     temp=orientation; 
     orientation = 1; 

     [self loadView]; 
     [self viewDidLoad]; 
    } 

    else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationFaceDown ||  [[UIDevice currentDevice] orientation] == UIDeviceOrientationFaceUp){ 

     temp=orientation; 
    } 

    else{ 
     temp=orientation; 
     orientation = 2; 
     [self loadView]; 
     [self viewDidLoad]; 
    } 
} 

EDIT를 얻을 수있는 viewDidLoad 전화 :

나는 문제를 발견했다. 내가 뭘하고있는 건이 하나를 덮어 쓰지 않고 self.view의 또 다른 인스턴스를 만드는 것이다. 이보기를 파괴하고 다시 초기화하는 쉬운 방법이 있습니까?

EDIT2 :

수정을 발견했다. jsds 명령에 따라 loadview 및 viewdidload 호출을 중단했습니다. 대신 loadview의 모든 코드를 loadview에서 호출 한 다른 함수로 옮겼습니다. 이 모든 코드는 UI (initview) 객체를 인스턴스화하고 방향에 따라 올바른 위치에 배치합니다.

그런 다음 뷰에서 모든 하위 뷰를 제거하는 또 다른 함수를 만듭니다. 그런 다음 방향 변경시이 함수와 initview를 호출하여 모든 하위 뷰를 삭제 한 다음 방향 변경시 다시 작성합니다.

답변

0

직접 loadView 또는 viewDidLoad를 호출해서는 안됩니다. 그것은 관리 할 프레임 워크에 달려 있습니다.

viewDidLoad의 뷰 경계를 기반으로 뷰의 위치를 ​​지정하거나 크기를 조정하는 경우에는 수행하지 마십시오. ViewWillLayoutSubviews로 이동하십시오. 장치 방향이 변경되면 자동으로 호출됩니다.

또는 autolayout 제약 조건을 사용하면 아무 것도하지 않아도됩니다.

+0

늦게 답장을 드려 죄송합니다. 이 문서는 어디에서 찾을 수 있습니까? 나는 이것의 예를 추적하는 데 약간의 어려움을 겪고있다. – user3009729

+0

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html https://developer.apple.com/library/ios/documentation/windowsviews/conceptual/viewpg_iphoneos/Introduction/Introduction .html https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html – jsd

+0

특히 이러한 메소드를 호출하지 말라는 참고 자료에 감사드립니다. Im 객관적인 c에서 약간 미경험. 문제를 해결하고이 문제가있는 사람을 위해 편집을 추가합니다. – user3009729

1

기본적으로 UIDeviceOrientation에는 6 개의 서로 다른 상태, 즉 2 개의 세로, 2 개의 가로, 그리고 앞면이 위로 향하게됩니다. 따라서 평면 위치에서 수직 위치로 기기를 집어 올리면 알림이 실행됩니다. 당신은 여전히 ​​트리거를 여러 번 받고 통지를 발견하면 당신은 당신이 체크 플래그와 함께 사용자 지정 논리를 사용해야 할 수도 두려워, 매크로 UIDeviceOrientationIsValidInterfaceOrientation

UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation]; 

    // Ignore changes in device orientation if unknown, face up, or face down. 
    if (!UIDeviceOrientationIsValidInterfaceOrientation(currentOrientation)) { 
     return; 
    } 

를 사용하여 알 수없는 상태 향의면을 위로 가게를 필터링 할 수 있습니다 이전 값과 현재 값나는 반응 코코아 프레임 워크를 사용하기 때문에 내 경우

는, 다음 코드는 나를 위해 작동 : 여기

if (IS_IPAD) { @weakify(self); [[[[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIDeviceOrientationDidChangeNotification object:nil] takeUntil:[self rac_willDeallocSignal]] map:^id (NSNotification *notification) { return @([[UIDevice currentDevice] orientation]); }] filter:^BOOL(NSNumber *deviceOrientationNumber) { UIDeviceOrientation currentOrientation = [deviceOrientationNumber integerValue]; //We ignore the UIDeviceOrientationUnknown, UIDeviceOrientationFaceUp and UIDeviceOrientationFaceDown return UIDeviceOrientationIsValidInterfaceOrientation(currentOrientation); }] distinctUntilChanged] subscribeNext:^(id x) { @strongify(self); //do something here... }]; }

distinctUntilChanged 방법은 코드 방향이 새로운 유효로 변경하는 경우에만 트리거됩니다 확인합니다 값.