UIViewController包含animation,如Google+

要理解我想要解释的内容,最好的方法是打开Google+应用,然后点按主post中显示的post背景中的任意位置。

当你点击它时,整个post会在屏幕中心移动,并且会在下面加载post的评论。

我认为这是一个常见的UIViewController遏制情况,其中一个UIViewController在另一个。 但是,这个post如何能够animation地移动它,并在包含的视图控制器中“转移”自己?

我已经尝试创build一个简单的button,并显示一个UIViewController作为另一个popup窗口,但不知道如何做Google+的应用程序(和其他人),而不是做。

UPDATE

这里是截图。

在这里输入图像说明在这里输入图像说明

正如你所看到的,当你点击一个post时,这个post向上滑动,并成为一个新的包含UIViewController

正如已经指出的,有很多方法来实现这个用户界面,但一种方法是从桌面视图单元中抓取视图,将其移动到一个新的背景,并改变其框架。 而当你把它放回去时,只要逆转这个过程。

稍微详细一点,可能如下:

  1. 在单元格中,我有一个容器视图,它是一个滚动视图(其用户交互通常是禁用的)。

  2. 当用户点击它时,

    • 创build一个透明的新的背景视图,占据整个屏幕;

    • 给这个背景一个轻敲手势识别器,可以稍后逆转过程;

    • 将单元格的容器视图从单元格移动到这个新的背景视图(使用convertRect所以它不能移动);

    • animation通过转换轻微缩小容器(一个微妙的效果,使您在视图上“推倒”的效果);

    • 在该animation的完成块中,启动一个新animation:

      • 恢复转换回身份;

      • 将背景背景颜色设置为基本不透明(但不完全如此)的颜色;

      • animation容器视图的大小以占用更多的屏幕

      • 继续在该容器视图上启用用户交互,以便您可以滚动;

  3. 在我们的背景上有一个点击手势的处理程序,可以逆转这个过程。

从而:

 - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:NO]; PostCell *cell = (id)[tableView cellForRowAtIndexPath:indexPath]; // create subview to obscure the table view behind us UIView *backdropView = [[UIView alloc] initWithFrame:self.view.bounds]; backdropView.backgroundColor = [UIColor clearColor]; [self.view addSubview:backdropView]; self.backdropView = backdropView; // add a tap gesture so we can reverse the process [backdropView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]]; // move the cell's container view to the backdrop view, preserving its location on the screen // (so it doesn't look like it moved) self.viewToMove = cell.containerView; self.viewToMoveOriginalCell = cell; self.viewToMoveOriginalFrame = cell.containerView.frame; // figure out where this goes on the backdrop CGRect frame = [self.viewToMoveOriginalCell convertRect:self.viewToMoveOriginalFrame toView:self.backdropView]; // move it there (though it won't appear to move yet, we're just changing its superview) [self.backdropView addSubview:self.viewToMove]; self.viewToMove.frame = frame; // now do the animation [UIView animateWithDuration:0.25 delay:0.0 options:0.0 animations:^{ // first shrinking it a bit self.viewToMove.transform = CGAffineTransformMakeScale(0.95, 0.95); } completion:^(BOOL finished) { // finally restoring the size and making it bigger // (and reveal the backdrop that obscures the tableview) [UIView animateWithDuration:0.5 animations:^{ CGFloat horizontalMargin = (self.view.bounds.size.width - frame.size.width) / 2.0; backdropView.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8]; self.viewToMove.transform = CGAffineTransformIdentity; self.viewToMove.frame = CGRectMake(horizontalMargin, kVerticalMargin, self.view.bounds.size.width - 2.0 * horizontalMargin, self.view.bounds.size.height - 2.0 * kVerticalMargin); }]; self.viewToMove.userInteractionEnabled = YES; }]; } - (void)handleTapGesture:(UITapGestureRecognizer *)gesture { [UIView animateWithDuration:0.5 delay:0.0 options:0 animations:^{ // in case user scrolled in content view, scroll back [self.viewToMove setContentOffset:CGPointZero animated:YES]; // figure out where to resize view on container view so it's // going to end up where it will end up in the cell CGRect frame = [self.viewToMoveOriginalCell convertRect:self.viewToMoveOriginalFrame toView:self.backdropView]; self.viewToMove.frame = frame; // make the back drop appear to gracefully disappear self.backdropView.backgroundColor = [UIColor clearColor]; // shrink content view a tad in the process self.viewToMove.transform = CGAffineTransformMakeScale(0.95, 0.95); } completion:^(BOOL finished) { // when done with that animation ... [UIView animateWithDuration:0.25 delay:0.0 options:0 animations:^{ // restore the size of the content view self.viewToMove.transform = CGAffineTransformIdentity; } completion:^(BOOL finished) { // when all done, put the content view back // in the cell [self.viewToMoveOriginalCell addSubview:self.viewToMove]; self.viewToMove.frame = self.viewToMoveOriginalFrame; // turn off its user interaction again self.viewToMove.userInteractionEnabled = NO; // and now safely discard the backdrop [self.backdropView removeFromSuperview]; }]; }]; } 

如你所知,这是所有标准的表格视图等。 如果你想使用视图控制器遏制(例如,如果视图有重要的用户交互),你也可以做到这一点。 它不会影响UX的单元格容器视图的增长/缩小。

此外,这一切都是非自动布局。 你可以使用自动布局来做到这一点,但更多的是一个麻烦,恕我直言,因为你可能需要删除和添加约束,但肯定可以做到。