繁体   English   中英

当前的ChildView控制器

[英]Current ChildView Controller

我正在尝试在我的ViewController上实现SwipeGesture。

我当前面临的问题是我无法确定当前显示的childview控制器是什么。

swipeGesture已添加到容器视图控制器。 然后必须确定父子关系中当前显示的VC是什么,然后向右或向左移动。

如果您在谈论自定义容器视图控制器,那么容器控制器的工作就是跟踪这一点。 因此,您可能拥有自己的@property ,可以跟踪您正在使用的@property ,并在您通过滑动而从transitionFromController调整时对其进行调整。 因此,您可能具有一个数字属性,该属性在向右移动时递增,而在向左移动时递减。

通常,(如果您只是想跟踪传递给transitionFromViewController的哪个“从”控制器),有两种方法。 清单14-3中的“ 添加 视图控制器编程指南”中的添加子控制器暗含了一种方法

在这种情况下,您可以在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]

在我正在从事的项目中,我有许多视图控制器,每个视图控制器都将自己的导航控制器添加到父视图控制器中。 我知道最初输入的孩子,但是我执行以下操作来查找该孩子当前显示的孩子:

[myKnownViewController.childViewControllers objectAtIndex:0].navigationController.topViewController

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM