2013-01-18 87 views
2

我想在我的viewcontroller上實現一個SwipeGesture。當前ChildView控制器

我目前面臨的問題是我無法確定當前顯示的子視圖控制器是什麼。

swipeGesture被添加到容器視圖控制器。然後必須確定當前顯示的VC在父子關係中是什麼,然後向右或向左移動。

回答

5

如果您正在談論自定義容器視圖控制器,那麼容器控制器的工作就是跟蹤這一點。因此,您可能擁有自己的@property,用於跟蹤您正在使用哪一個,並根據滑動結果調整爲transitionFromController。所以你可能會有一個數值屬性,當你走向右邊時,它會增加,並且當你走向左邊時,它會遞減。

一般來說(如果你只是想跟蹤你傳遞給transitionFromViewController的那個「from」控制器),有兩種方法。清單14-3在「視圖控制器編程指南」的Adding a child controller中隱含了一種方法。

在這種情況下,您在viewDidLoad中爲第一個視圖控制器執行addChildViewController。但是,在這種情況下,您不需要通過addChildViewController加載其他子視圖控制器,而是讓您的方法完成轉換(如清單14-3所示)。

如果你這樣做,你可以抓住[self.childViewControllers lastObject],這將是你的「當前」子控制器。所以,這可能看起來像:

@interface ViewController() 

@property (nonatomic) NSInteger currentIndex; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UIViewController *initialController = ... // set your initial controller 

    [self addChildViewController:initialController]; 
    initialController.view.frame = self.containerView.bounds; 
    [self.containerView addSubview:initialController.view]; 
    [initialController didMoveToParentViewController:self]; 

    UISwipeGestureRecognizer *gesture; 

    gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)]; 
    gesture.direction = UISwipeGestureRecognizerDirectionRight; 
    [self.containerView addGestureRecognizer:gesture]; 

    gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)]; 
    gesture.direction = UISwipeGestureRecognizerDirectionLeft; 
    [self.containerView addGestureRecognizer:gesture]; 

} 

- (void) handleSwipe:(UISwipeGestureRecognizer *)gesture 
{ 
    if (gesture.direction == UISwipeGestureRecognizerDirectionLeft && self.currentIndex < (kMaxIndex - 1)) 
    { 
     self.currentIndex++; 

     UIViewController *newController = ... // set your new controller 
     UIViewController *oldController = [self.childViewControllers lastObject]; 

     [self cycleFromViewController:oldController 
        toViewController:newController 
          direction:gesture.direction]; 

    } 
    else if (gesture.direction == UISwipeGestureRecognizerDirectionRight && self.currentIndex > 0) 
    { 
     self.currentIndex--; 

     UIViewController *newController = ... // set your new controller 
     UIViewController *oldController = [self.childViewControllers lastObject]; 

     [self cycleFromViewController:oldController 
        toViewController:newController 
          direction:gesture.direction]; 
    } 
} 

- (void) cycleFromViewController:(UIViewController*) oldController 
       toViewController:(UIViewController*) newController 
         direction:(UISwipeGestureRecognizerDirection)direction 
{ 
    [oldController willMoveToParentViewController:nil]; 
    [self addChildViewController:newController]; 

    newController.view.frame = oldController.view.frame; 

    UIViewAnimationOptions options; 

    if (direction == UISwipeGestureRecognizerDirectionRight) 
     options = UIViewAnimationOptionTransitionFlipFromLeft; 
    else if (direction == UISwipeGestureRecognizerDirectionLeft) 
     options = UIViewAnimationOptionTransitionFlipFromRight; 

    [self transitionFromViewController:oldController 
         toViewController:newController 
           duration:0.33 
           options:options 
          animations:^{ 
           [oldController removeFromParentViewController]; 
          } 
          completion:^(BOOL finished) { 
           [newController didMoveToParentViewController:self]; 
          }]; 
} 

,我已經看到了一些人做的另一種模式是在viewDidLoad通過addChildViewController加載所有的勢子控制器。我個人不喜歡這種方法,但我知道人們這樣做,它的工作正常。

但是,如果你這樣做,你不能再依靠childViewControllers來知道哪個控制器是當前控制器。在這種情況下,您必須爲currentChildController定義您自己的類屬性。所以它可能看起來像這樣:

@interface ViewController() 

@property (nonatomic, strong) UIViewController *currentChildController; 
@property (nonatomic) NSInteger currentIndex; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [self addChildViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"ChildOne"]]; 
    [self addChildViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"ChildTwo"]]; 
    [self addChildViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"ChildThree"]]; 

    self.currentChildController = self.childViewControllers[0]; 

    self.currentChildController.view.frame = self.containerView.bounds; 
    [self.containerView addSubview:self.currentChildController.view]; 

    for (UIViewController *controller in self.childViewControllers) 
     [controller didMoveToParentViewController:self]; 

    UISwipeGestureRecognizer *gesture; 

    gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)]; 
    gesture.direction = UISwipeGestureRecognizerDirectionRight; 
    [self.containerView addGestureRecognizer:gesture]; 

    gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)]; 
    gesture.direction = UISwipeGestureRecognizerDirectionLeft; 
    [self.containerView addGestureRecognizer:gesture]; 
} 

- (void) cycleFromViewController:(UIViewController*) oldController 
       toViewController:(UIViewController*) newController 
         direction:(UISwipeGestureRecognizerDirection) direction 
{ 
    self.currentChildController = newController; 

    newController.view.frame = oldController.view.frame; 

    UIViewAnimationOptions options; 

    if (direction == UISwipeGestureRecognizerDirectionRight) 
     options = UIViewAnimationOptionTransitionFlipFromLeft; 
    else if (direction == UISwipeGestureRecognizerDirectionLeft) 
     options = UIViewAnimationOptionTransitionFlipFromRight; 

    [self transitionFromViewController:oldController 
         toViewController:newController 
           duration:0.33 
           options:options 
          animations:^{ 
          } 
          completion:nil]; 
} 

- (void) handleSwipe:(UISwipeGestureRecognizer *)gesture 
{ 
    if (gesture.direction == UISwipeGestureRecognizerDirectionLeft && self.currentIndex < (kMaxIndex - 1)) 
    { 
     self.currentIndex++; 

     UIViewController *oldController = self.currentChildController; 
     UIViewController *newController = self.childViewControllers[self.currentIndex]; 

     [self cycleFromViewController:oldController 
        toViewController:newController 
          direction:gesture.direction]; 

    } 
    else if (gesture.direction == UISwipeGestureRecognizerDirectionRight && self.currentIndex > 0) 
    { 
     self.currentIndex--; 

     UIViewController *oldController = self.currentChildController; 
     UIViewController *newController = self.childViewControllers[self.currentIndex]; 

     [self cycleFromViewController:oldController 
        toViewController:newController 
          direction:gesture.direction]; 
    } 
} 

這些是兩種邏輯方法。

順便說一下,第一種方法並不排除讓你自己的類屬性知道你在使用哪個控制器,有時候這很有用(例如,如果你使用的動畫類型取決於你是否要去到「右」或「左」),但除非是這種情況,你可以離開只看[self.childViewControllers lastObject]

+1

謝謝!這可能需要我花一些時間來審查所有這一切:) – jacobronniegeorge

0

在我正在研究的項目中,我有許多視圖控制器,每個都有自己的導航控制器添加到父視圖控制器我知道初始輸入的孩子,但我做了以下操作來查找當前顯示的孩子的孩子:

[myKnownViewController.childViewControllers objectAtIndex:0].navigationController.topViewController 
相關問題