了解我要解释的内容的最佳方式是打开 Google + 应用,然后点按主要帖子中显示的帖子的背景中的任意位置。
当你点击它时,整个帖子会在屏幕中央移动一个漂亮的动画,并在帖子的下方加载帖子的评论。
我认为这是一个常见的UIViewController
遏制场景,其中一个UIViewController
位于另一个内。但是帖子如何能够动态地移动它并在包含的视图控制器中“转移”它自己?
我已经尝试创建一个简单的按钮,并将UIViewController
显示为彼此的弹出窗口,但不知道如何执行Google+应用(和其他人)的操作。
更新
这是截图。
正如您在点击帖子时所看到的那样,帖子会向上滑动并成为新的UIViewController
。
答案 0 :(得分:2)
正如已经指出的,有很多方法可以实现这个UI,但是一种方法是从tableview单元格中取出视图,将其移动到某个新的背景上,然后更改其框架。当你把它放回去时,只需逆转这个过程。
稍微详细一点,可能如下:
在单元格中,我有一个容器视图,它是一个滚动视图(通常禁用其用户交互)。
当用户点击它时,
创建一个透明的新背景视图,占据整个屏幕;
为该背景提供一个轻击手势识别器,可以在以后改变该过程;
将单元格的容器视图从单元格移动到此新背景视图(使用convertRect
,因此它尚未移动);
通过转换动画轻微收缩容器(一种微妙的效果,可以让你在视图中按下#34;#/ p>
在该动画的完成块中,启动一个新动画:
将转换恢复为标识;
将背景幕背景颜色设置为很大程度上不透明(但并非完全如此)的颜色;
为容器视图的大小设置动画以占用更多屏幕
继续并在该容器视图上启用用户交互,以便您可以滚动;
在我们的背景幕上设置一个点击手势的处理程序,以反转该过程。
因此:
- (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。
此外,这一切都是非自动布局。你可以用自动布局做到这一点,但更麻烦的是,恕我直言,因为你可能不得不删除和添加约束,但肯定可以做到。