2

ビューコントローラーに SwipeGesture を実装しようとしています。

現在直面している問題は、現在表示されている childview コントローラーが何であるかを判断できないことです。

コンテナー ビュー コントローラーに swipeGesture が追加されます。次に、現在表示されている VC が親子関係にあるかどうかを判断し、右または左に移動する必要があります。

4

2 に答える 2

5

カスタム コンテナ ビュー コントローラについて話している場合、これを追跡するのはコンテナ コントローラの仕事です。@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]ます。

于 2013-01-19T05:48:35.383 に答える
0

私が取り組んでいるプロジェクトでは、多くのView Controllerがあり、それぞれに独自のNavigation ControllerがParent View Controllerに追加されています。私は最初のエントリの子を知っていますが、現在表示されている子の子を見つけるために次のことを行います。

[myKnownViewController.childViewControllers objectAtIndex:0].navigationController.topViewController
于 2013-02-01T00:01:16.447 に答える