ビューコントローラーに SwipeGesture を実装しようとしています。
現在直面している問題は、現在表示されている childview コントローラーが何であるかを判断できないことです。
コンテナー ビュー コントローラーに swipeGesture が追加されます。次に、現在表示されている VC が親子関係にあるかどうかを判断し、右または左に移動する必要があります。
ビューコントローラーに SwipeGesture を実装しようとしています。
現在直面している問題は、現在表示されている childview コントローラーが何であるかを判断できないことです。
コンテナー ビュー コントローラーに swipeGesture が追加されます。次に、現在表示されている VC が親子関係にあるかどうかを判断し、右または左に移動する必要があります。
カスタム コンテナ ビュー コントローラについて話している場合、これを追跡するのはコンテナ コントローラの仕事です。@property
そのため、自分がどちらを使用しているかを追跡しtransitionFromController
、スワイプの結果としてそれを調整する独自のものを持っているかもしれません. したがって、右に行くほど増加し、左に行くほど減少する数値プロパティがあるとします。
一般に (どの "from" コントローラーに渡しているかを追跡したいだけの場合transitionFromViewController
)、2 つの方法があります。View Controller Programming GuideのAdding a child controllerの14-3 をリストすることで、1 つのアプローチが暗示されます。
このシナリオでは、最初の View Controller に対してviewDidLoad
実行します。addChildViewController
ただし、このシナリオでは、この時点で他の子View Controllerをロードするの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];
}];
}
一部の人々が行っているのを私が見た他のモデルは、 in を介して潜在的な子コントローラーをすべてロードすることaddChildViewController
ですviewDidLoad
。私は個人的にこのアプローチが好きではありませんが、人々がこのようにしてうまくいくことは知っています。
しかし、このようにする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];
}
}
これらは2つの論理的なアプローチです。
ところで、最初のアプローチは、自分がどのコントローラーを使用しているかを知るために独自のクラス プロパティを持つことを妨げません。 」または「左に」ですが、そうでない場合は、 を見るだけで済み[self.childViewControllers lastObject]
ます。
私が取り組んでいるプロジェクトでは、多くのView Controllerがあり、それぞれに独自のNavigation ControllerがParent View Controllerに追加されています。私は最初のエントリの子を知っていますが、現在表示されている子の子を見つけるために次のことを行います。
[myKnownViewController.childViewControllers objectAtIndex:0].navigationController.topViewController