当前的ChildView控制器(Current ChildView Controller)

编程入门 行业动态 更新时间:2024-10-26 08:20:34
当前的ChildView控制器(Current ChildView Controller)

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

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

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

I am trying to implement a SwipeGesture on my viewcontroller.

The issue I am facing currently is that I cannot determine what the currently displayed childview controller is.

The swipeGesture is added to the container view controller. And then must determine what is the currently displayed VC is in the parent-child relationship, then move to the right or left.

最满意答案

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

一般情况下(如果您只是想跟踪哪个“从”控制器传递给transitionFromViewController ),有两种方法。 清单14-3在添加 View 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]就可以逃脱。

If you are talking about custom container view controller, it's the job of the container controller to keep track of this. So, you might have your own @property that keeps track of which one you're on, and adjust it as you transitionFromController as a result of a swipe. So you might have a numeric property that you increment as you go to the right and that you decrement as you go to the left.

In general (if you're just trying to keep track of which "from" controller you're passing to transitionFromViewController), there are two approaches. One approach is implied by listing 14-3 in Adding a child controller of the View Controller Programming Guide.

In this scenario, in viewDidLoad you perform addChildViewController for the first view controller with. You do not, in this scenario, load the other child view controllers via addChildViewController at this point, though, but rather you let your method that does the transitioning take care of that (as in Listing 14-3).

If you do it this way, you can just grab [self.childViewControllers lastObject], and that will be your "current" child controller. So, that might look like:

@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]; }]; }

The other model that I've seen some people do is to load all of the potential child controllers via addChildViewController in viewDidLoad. I don't personally like this approach, but I know people do it this way and it works fine.

But if you do it this way, you can no longer rely upon childViewControllers to know which controller is the current one. In that case, you have to define your own class property for the currentChildController. So it might look something like:

@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]; } }

Those are the two logical approaches.

By the way, the first approach doesn't preclude having your own class property to know which controller you're on, and sometimes that's useful (e.g. if the type of animation you employ is contingent upon whether you're going to the "right" or to the "left), but unless that's the case, you can get away with just looking at [self.childViewControllers lastObject].

更多推荐

本文发布于:2023-04-27 20:33:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1329053.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:控制器   ChildView   Controller   Current

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!