1

我有一个网格视图。该网格中的每个单元格都是可点击的。如果单击单元格,则必须将另一个视图控制器呈现为模态视图控制器。呈现的视图控制器必须从右向左滑入。之后,可以通过幻灯片关闭 modalviewcontroller。我如何实现这一目标?我有一些图片来展示它:

在此处输入图像描述

两个视图都是独立的视图控制器。

[解决方案]

马修的回答为我指明了正确的方向。我需要的是一个 UIPanGestureRecognizer。因为 UISwipeGestureRecognizer 只注册一次滑动,我需要视图跟随用户的手指。我做了以下事情来完成它:

如果在我的 UICollectionView 中点击了我的单元格,则需要弹出额外的视图。所以我首先实现了以下代码:

/* The next piece of code represents the action called when a touch event occours on
 one of the UICollectionviewCells.
 */

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

    NSString* release_id = releases[indexPath.row][0];

    // Next boolean makes sure that only one new view can be seen. In the past, a user can click multiple cells and it allocs multiple instances of ReleaseViewController.
    if(releaseViewDismissed) {
        // Alloc UIViewController and initWithReleaseID does a request to a server to initialize some data.
        ReleaseViewController *releaseViewController = [[ReleaseViewController alloc] initWithReleaseID: release_id];
        // Create a new UIView and assign the height and width of the grid
        UIView *releaseViewHolder = [[UIView alloc] initWithFrame:CGRectMake(gridSize.width, 0, gridSize.width, gridSize.height)];
        // Add the view of the releaseViewController as a subview of the newly created view.
        [releaseViewHolder addSubview:releaseViewController.view];
        // Then add the UIView with the view of the releaseViewController to the current UIViewController's view.       
        [self.view addSubview:releaseViewHolder];
        // Place the x coordinate of the new view to the same as width of the screen. Then after that get the x to 0 with an animation. 
        [UIView animateWithDuration:0.3 animations:^{
            releaseViewHolder.frame = CGRectMake(0, 0, releaseViewHolder.frame.size.width, releaseViewHolder.frame.size.height);

             // This is important. alloc an UIPanGestureRecognizer and set the method that handles those events to handleSwipes.
            _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipes:)];
            // Add the UIPanGestureRecognizer to the created view.
            [releaseViewHolder addGestureRecognizer:_panGestureRecognizer];

            releaseViewDismissed = NO;

        }];

    }

}

然后我的handleSwipes如下:

-(void)handleSwipes:(UIPanGestureRecognizer *)sender {

    CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];
    CGPoint translation = [sender translationInView:sender.view];
    CGRect newFrame = [sender view].frame;

    [sender setTranslation:CGPointZero inView:sender.view];

    if (sender.state == UIGestureRecognizerStateChanged)
    {

        newFrame.origin.x = newFrame.origin.x + translation.x;
        // Makes sure it can't go beyond the left of the screen.
        if(newFrame.origin.x > 0) {

            [sender view].frame = newFrame;

        }

    }

    if(sender.state == UIGestureRecognizerStateEnded){

        CGRect newFrame = [sender view].frame;

        CGFloat velocityX = (0.3*[(UIPanGestureRecognizer*)sender velocityInView:self.view].x);

        // If the user swipes less then half of the screen, it has to bounce back.
        if(newFrame.origin.x < ([sender view].bounds.size.width/2)) {
            newFrame.origin.x = 0;
        }

        // If a user swipes fast, the velocity is added to the new x of the frame.
        if(newFrame.origin.x + velocityX > ([sender view].bounds.size.width/2)) {
            newFrame.origin.x = [sender view].bounds.size.width + velocityX;
            releaseViewDismissed = YES;
        }

        // Do it all with a animation.
        [UIView animateWithDuration:0.25
                         animations:^{

                            [sender view].frame = newFrame;

                         }
                         completion:^(BOOL finished){

                             if(releaseViewDismissed) {
                                 // Finally remove the new view from the superView.
                                 [[sender view] removeFromSuperview];
                             }

                         }];

    }

}
4

2 回答 2

0

我相信您需要的是以下内容:

创建另一个控制器来处理这两者之间的导航(例如 ContentViewController)。这个控制器应该有一个启用分页的 ScrollView。

如果您还不知道如何操作,这里有一个简单的教程:点击这里

单击单元格后,您必须:

  1. 创建要显示的新 ViewController。
  2. 启用分页并将此 ViewController 添加到 ContentViewController
  3. 强制分页到这个新创建的 ViewController

此外,您必须添加一些逻辑,以便当用户滑动以更改回第一页时,分页被禁用,直到单击新单元格以重复该过程。

于 2013-04-04T21:13:32.167 回答
0

如果您希望呈现的视图控制器从右向左滑入,则它不能是模态视图。@Juan 建议了一种实现从右到左并向后滑动的方法,但这会导致网格视图被新视图推开。如果您希望新视图在滑入时覆盖网格视图,您将需要接受模态视图的垂直滑动或编写自己的代码以从右侧滑入视图 - 后者实际上不会一切都那么困难*。

至于滑动返回,从模态呈现的视图或您自己动画的视图中执行此操作的最简单方法是使用UISwipeGestureRecognizer. 您创建识别器,告诉它要查找的滑动方向,并告诉它在滑动发生时调用什么方法。

*此方法的要点是创建一个UIView,将其添加为网格视图的子视图,并为其赋予与网格视图相同的框架但 x 位置等于视图的宽度,然后使用以下代码使视图从右侧动画化。

    [UIView animateWithDuration:0.3 animations:^{
        slidingView.frame = CGRectMake(0, 0, slidingView.frame.size.width, slidingView.frame.size.height);
    }];
于 2013-04-04T22:53:27.173 回答