2012-12-05 3 views
5

로그가있는 iOS 앱 (LognnViewController)이 있으며 사용자가 성공적으로 인증되면 간단한 세부 정보를 입력하기 위해 다른보기 (DetailEntryViewController)로 이동합니다.
세부 정보가 입력되면 사용자는 다양한 다른보기가있는 탭 컨트롤러 (TabViewController)로 구성된 앱의 주요 부분으로 이동합니다. LogInViewController는 DetailEntryViewController에 모달 구획을 수행하고 DetailEntryViewController은 TabViewController에 모달 구획을 수행하므로 모달 구획 체인이 응용 프로그램에 들어가게됩니다. 사용자가 로그 아웃 할 때 나는 LogInViewController 다시 모든 방법을 가고 싶어하지만 난 할 때모달 세그 체인

[self.presentingViewController dismissModalViewControllerAnimated:YES]; 

를 ... 그것은 TabViewController을 아빠와 나는 다시 대신 첫 LogInViewController의 DetailEntryViewController에서 끝낸다. 어떤 방식 으로든 첫 번째보기 컨트롤러로 쉽게 다시 돌아올 수 있습니까? 아니면이 모달 체인 레코드를 사용하면 그 일을 방지 할 수 있습니까? 사용자가 로그 아웃했지만 명백한 결정이 viewWillAppear에서 허용되지 않습니다 모달 컨트롤러를 해제 호출하는 경우 자동적으로 자신을 팝업 것 : viewDidLoad : 등

어떤을 나는 DetailEntryViewControllerviewWillAppear에서 몇 가지 코드를 넣어 밝은 생각이있어 이 일을 만드는 방법에 대한 아이디어?

답변

0
[self.navigationController popToRootViewControllerAnimated:YES]; 
+0

... 그것은 두 단계 모달 SEGUE 체인으로 나타내는 탭보기 컨트롤러입니다. –

+0

네비게이션 컨트롤러가없는 루트 뷰로 다시 "터지기"하고 있습니까? UINavigationController가 작성된 정확한 이유는 사용자가 요구하는 동작입니다. 내가 놓친 게 아니라면? –

+0

죄송합니다.보기 컨트롤러를 제거하는 일반적인 의미에서 "팝"을 사용하고 있습니다. 루트 탐색 컨트롤러가 없습니다. 모달 섹터를 통해 앱에 "터널"인 두 개의 표준보기 컨트롤러가 있고 다른보기가 포함 된 탭보기 컨트롤러가 있습니다. 나는 대답을 알아 냈다.하지만 아래를 보라. –

8

저는 이것이 앱을 구현하는 데 가장 적합한 구조라고 생각합니다. 모달 컨트롤러는 프로그램 흐름에 일시적으로 방해가되기 때문에 모달을 사용하여 주요 콘텐츠를 얻는 것이 이상적이지 않습니다. 이 작업을 수행하는 방법은 탭 막대 컨트롤러를 창에 대한 루트보기 컨트롤러로 만든 다음 첫 번째 탭의 컨트롤러에서 viewDidAppear 메서드로 로그인 컨트롤러를 모달로 표시하므로 곧바로 표시됩니다 (잠깐 볼 수 있습니다. segue의 속성 검사기에서 "애니메이션"상자를 선택 취소하지 않는 한 첫 번째 탭의보기). 하나의 컨트롤러에서 세부 컨트롤러를 표시 한 다음 두 모달 컨트롤러를 모두 닫아 주 컨텐츠로 돌아갑니다. 사용자가 로그 아웃하면 로그인 컨트롤러를 다시 나타냅니다. 이런 생각을 구현합니다. 첫 번째 탭의 뷰 컨트롤러에서 : 그냥했다 ...

-(IBAction)goBackToMain:(id)sender { 
    [self.view.window.rootViewController dismissViewControllerAnimated:YES completion:nil]; 
} 
1

이 그것을 알아 낸 자신을 :

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    _appStarting = YES; 
} 

-(void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    if (_appStarting) { 
     [self performSegueWithIdentifier:@"Login" sender:self]; 
     _appStarting = NO; 
    } 
} 

그런 다음 모달 (초 귀하의 경우) 마지막 뷰 컨트롤러에, 나는 버튼 방식이 "루트"뷰 컨트롤러 (LogInViewController)에 도착하는 또 하나 개의 수준을 가서이 트릭했던 것을 발견합니다 : 난 그냥 presentingViewController (DetailEntryViewController)를 받고 있어요 말했듯이

[[self.presentingViewController presentingViewController] dismissViewControllerAnimated:YES completion:nil]; 

을하고, n 하나 더 레벨 올라가서 그 컨트롤러의 발표자 (LogInViewController)를 얻는 것.

+1

나는 내 대답에서 말했듯이, 나는 이것이 좋은 구조라고 생각하지 않는다. 여러분과이 보드의 많은 사람들이 모달 섹터를 오용하고 있습니다. 모달 컨트롤러는 프로그램의 흐름을 일시적으로 중단시키는 것이지 주 내용에 도달하는 방법이 아닙니다. 그것은 효과가 있지만 좋은 디자인이라고 생각하지 않습니다. – rdelmar

+0

나는 여기서 완전히 동의하며, 네가 선택한 구조가 네비게이션 스택이 어떻게 사용되어야하는지 혼란스럽게 할 것이라고 믿는다. 다른 모달보기에 모달보기를 제시 한 다음 그 모서리를 탐색 할 이유가 없습니다. 여기 논리를 설명해 주시겠습니까? 모달보기는 표시되고 제거되어야합니다. 그 이상으로 탐색하려는 경우 이것이 올바른 선택이라고 생각하지 않으며이 구조에 너무 깊이 들어가기보다는 논리를 수정하는 것이 좋습니다. 그러나 각자에게는 자신이 있습니다. ;-) –

1

나는 비슷한 문제가 있었고 "모달 체인"은 제한되지 않았습니다. 저는 답변에있는 논점과 아래에 다른 것에 대해 언급 된 모달 쎄그 (modal segues)에 대한 의견에 동의하지만, 모달 쎄그의 "수평 플립"애니메이션이 좋았고 그것들을 복제하는 더 쉬운 방법을 찾을 수 없었습니다 ... 또한 일반적으로 저는 모달 컨트롤러를 연결하는 것과 같은 다른 일을 성취하기 위해 설계된 것을 사용하는 데있어 잘못된 점을 보지 마십시오. 반복 된 "부분 컬"애니메이션은 일부 앱의 일부 시나리오에도 적용될 수 있습니다.

그래서 제어기의 속성으로 모달 컨트롤러의 스택을 구현 :

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([[segue identifier] isEqualToString:@"modalSegue"]) { 
     ModalViewController *controller = 
      (ModalViewController *)[segue destinationViewController]; 

     controller.modalControllers = [NSMutableArray arrayWithObject: controller]; 
    } 
} 
을 : 제 모달 SEGUE 모달되지 컨트롤러 prepareForSegue 방법에서 생성 된 스택을 실행

@interface ModalViewController : UIViewController 
@property (nonatomic, retain) NSMutableArray *modalControllers; 
@end 

하나 모달 제어기는 다른 이동하면

대상이

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([[segue identifier] isEqualToString:@"modalSegue"]) { 
     ModalViewController *destController = 
      (ModalViewController *)[segue destinationViewController]; 

     // add destination controller to stack 
     destController.modalControllers = _modalControllers; 
     [destController.modalControllers addObject: destController]; 
    } 
} 
,617 (ModalViewCotroller의 방법에서) 스택에 추가

전체 스택을 한 번에 닫으려면 가장 까다로운 부분이었습니다. 다음 해고가 완료되기 전에 이전 컨트롤러를 닫을 수 없으므로 순환이 작동하지 않으며 재귀 블록 만이 메모리 누수를 피하면서 트릭을 수행했습니다. (나는 그것을 확인하기 위해 아직,하지만 난이 this에 의존) 까다로운는 :

더 탐색 컨트롤러가 없습니다
- (IBAction)dismissAllModalControllers: (id)sender 
{ 
    // recursive block that dismisses one auth controller 
    // all these dances are to avoid leaks with ARC 
    typedef void (^voidBlockType)(); 
    __block void (^dismissController)(); 
    voidBlockType __weak dismissCopy = ^void(void) { 
     dismissController(); 
    }; 
    dismissController = ^void(void) { 
     int count = [_modalControllers count]; 
     if (count > 0) { 
      // get last controller 
      UIViewController *controller = 
       (UIViewController *)[_modalControllers lastObject]; 
      // remove last controller 
      [_modalControllers removeLastObject]; 
      // dismiss last controller 
      [controller 
       // the first controller in chain is dismissed with animation 
       dismissViewControllerAnimated: count == 1 ? YES : NO 
       // on completion call the block that calls this block recursively 
       completion: dismissCopy]; 
     } 
    }; 

    // this call dismisses all modal controllers 
    dismissController();   
}