我想在我的viewcontroller上實現一個SwipeGesture。當前ChildView控制器
我目前面臨的問題是我無法確定當前顯示的子視圖控制器是什麼。
swipeGesture被添加到容器視圖控制器。然後必須確定當前顯示的VC在父子關係中是什麼,然後向右或向左移動。
我想在我的viewcontroller上實現一個SwipeGesture。當前ChildView控制器
我目前面臨的問題是我無法確定當前顯示的子視圖控制器是什麼。
swipeGesture被添加到容器視圖控制器。然後必須確定當前顯示的VC在父子關係中是什麼,然後向右或向左移動。
如果您正在談論自定義容器視圖控制器,那麼容器控制器的工作就是跟蹤這一點。因此,您可能擁有自己的@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]
在我正在研究的項目中,我有許多視圖控制器,每個都有自己的導航控制器添加到父視圖控制器我知道初始輸入的孩子,但我做了以下操作來查找當前顯示的孩子的孩子:
[myKnownViewController.childViewControllers objectAtIndex:0].navigationController.topViewController
謝謝!這可能需要我花一些時間來審查所有這一切:) – jacobronniegeorge