2013-09-03 5 views
1

내 응용 프로그램의 루트보기 컨트롤러는 UISplitViewController입니다. 마스터 및 세부보기 컨트롤러는 두 개의 탐색 컨트롤러입니다. 내가 원하는 것은 특정보기 컨트롤러가 마스터보기에서 표시되면 스 와이프 동작으로 숨기거나 표시 할 수있는 마스터보기가 필요합니다. 루트보기 컨트롤러를 설정하기 전에 대리자 메서드를 구현하고 presentWithGesture를 yes로 설정하면 네비게이션 스택에있는 모든 뷰 컨트롤러에 대한 일반적인 동작으로 작동합니다. 하지만 하나의보기 컨트롤러에만 필요합니다. 보유하고있는 아이디어를 공유하십시오.가로 모드에서 하나의보기 컨트롤러에 대해서만 UISplitViewController에서 마스터보기 활성화/숨기기 설정

+0

보세요 : -http : //stackoverflow.com/questions/18208410/fill-master-and-detail-view-in-full-screen-mode-of-ipad/18225085#18225085 –

답변

2

이전에는 rotation 이벤트를 트리거하고 "shouldHideViewController"대리자 메서드를 구현하여이 작업을 수행했습니다. 그런 식으로하는 가장 큰 문제는 드물게 좋아 보이지 않는다는 것입니다. 때로는 움직이는 것처럼 보일 뿐이지 다른 것들은 화면에서 서두르는 경우도 있습니다. 나는 아래 함수를 작성하고 그것을 숨기거나 주인을 보여 주도록 내 appdelegate에 두었다. 멋진 애니메이션으로 숨겨져 있으며 지금까지는 나를 위해 훌륭하게 작동했습니다 (참고 :이 질문에 대한 나의 예비 응답 편집).

이 함수는 프레임을 애니메이션으로 조정하여 masterViewController를 숨기거나 표시합니다. 애니메이션을 끝낼 때 완료 블록을 전달하여 호출 컨트롤러가 애니메이션을 순서대로 수행해야 레이아웃을 멋지게 볼 수 있습니다. 필요가 없으면 nil을 전달하십시오. 이것은 autolayout을 사용할 때 가장 잘 작동합니다.

#pragma mark - UISplitView Hide Master 
/** Will hide/show masterViewController by adjusting it's frame with an animation. 
* Can pass a completion block to be called when the animation is finished incase calling 
* controller needs to do animations in-order for view. Pass nil if not needed. 
@param completionBlock - accepts an optional completion block or nil arguement. The completion block is called when the hide/unhide animation is complete. 
@return void 
*/ 
-(void)toggleHideMaster:(void(^)(void))completionBlock 
{ 
    __weak MyAppDelegate *delegate = self; 
    __weak UISplitViewController *splitView = (UISplitViewController*)self.window.rootViewController; 

    // Adjust the detailView frame to hide/show the masterview 
    [UIView animateWithDuration:0.20f 
          delay:0.0f 
         options:UIViewAnimationOptionCurveEaseInOut 
        animations:^(void) 
    { 
     CGRect selfFrame = splitView.view.frame; 

     // Get the width of the master view controller - so we know how far to animate. 
     CGFloat deltaWidth = delegate.masterNavigationController.topViewController.view.frame.size.width; 

     if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) 
     { 
      if (!delegate.masterIsHidden) 
      { 
       selfFrame.size.width += deltaWidth; 
       selfFrame.origin.x -= deltaWidth; 
      } 
      else 
      { 
       selfFrame.size.width -= deltaWidth; 
       selfFrame.origin.x += deltaWidth; 
      } 
     } 
     else 
     { 
      if(!delegate.masterIsHidden) 
      { 
       selfFrame.size.height += deltaWidth; 
       if (splitView.interfaceOrientation == UIInterfaceOrientationLandscapeRight) 
       { 
        selfFrame.origin.y -= deltaWidth; 
       } 
      } 
      else 
      { 
       selfFrame.size.height -= deltaWidth; 
       if (splitView.interfaceOrientation == UIInterfaceOrientationLandscapeRight) 
       { 
        selfFrame.origin.y += deltaWidth; 
       } 
      } 
     } 

     [splitView.view setFrame:selfFrame]; 
    }completion:^(BOOL finished){ 
     if (finished) 
     { 
      delegate.masterIsHidden = !delegate.masterIsHidden; 

      if (completionBlock) 
      { 
       completionBlock(); 
      } 
     } 
    }]; 
} 

/** Method is called by the Navigation controller when the ipad is rotated. Also called when we come from the background incase we were in a full screen state. This is to get the master controller 
    back into the correct state. 
    @return void 
*/ 
- (void)updateHideMasterOnRotation { 
    if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) { 
     if (self.masterIsHidden) { 
      self.masterIsHidden = NO; 
      [self toggleHideMaster:nil]; 
     } 
    } 
} 
// I observe the rotation in my detailview's navigationcontroller like this. 
// We track this on the navigation controller to globally reset the master hidden state to where it needs to be. This won't take into account previously passed completion blocks. If needed that can be handled in the view controller implementing the hideable splitview. 
// Again - additional things will need to be considered if supporting portrait - like resetting if we rotate to a portrait orientation. 
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    MYAppDelegate *appDelegate = (MYAppDelegate*)[UIApplication sharedApplication].delegate; 

    [appDelegate updateHideMasterOnRotation]; 
} 

이제 마스터보기를 애니메이션으로 숨기고 모든 viewcontroller에서 호출 할 수있는 패턴이 있습니다. 이 예는 가로로 고정 된 앱을위한 것이지만 가로 회전 (FYI)을 모두 지원하므로 패턴을 업데이트하여 몇 가지 조건으로 세로로 작업 할 수 있습니다. 또한이 기능에 대한 최소한의 접근을 허용합니다. 전에는 MGSplitviewcontroller를 살펴 봤지만 멋지지만 제공하는 모든 기능이 필요하지는 않습니다. 나는 또한 그들이하는 일의 대부분을 필요로하지 않을 때 다른 사람들에게 의존하는 의존성을 가지고있는 것을 좋아하지 않는다.

편집 12/10 -이 답변에 iOS8 지원이 추가되었습니다. iOS7에서는 splitview 프레임의 xy 좌표가 반대로되었습니다. iOS8에서 그들은 예상대로입니다. 그래서 우리는 이것을 이것을 고려할 필요가 있습니다. 프레임은 iOS8에서 순환 게재시에도 변경되지 않으므로 iOS에서 순환 게재시에만 업데이트됩니다. < 8.0.

누군가가 도움이되기를 바랍니다.

해피 프로그래밍.

관련 문제