理解我想要解释的内容的最好方法是打开Google+应用程序并点击主帖子流中显示的帖子背景中的任意位置。
当您点击它时,整个帖子会以漂亮的动画自动移动到屏幕中央,并在其下方加载帖子的评论。
我认为这是一个常见的UIViewController
遏制场景,其中一个UIViewController
在另一个里面。但是帖子如何能够动画地移动它并在容器视图控制器内“转移”自身呢?
我已经尝试创建一个简单的按钮并显示UIViewController
作为彼此的弹出窗口,但不知道如何执行 Google+ 应用程序(和其他应用程序)的操作。
UPDATE
这是屏幕截图。
正如您所看到的,当您点击帖子时,帖子会向上滑动并成为新的包含内容UIViewController
.
正如已经指出的,有很多方法可以实现此 UI,但一种方法是从 tableview 单元格中获取视图,将其移动到某个新背景上,然后更改其框架。当你把它放回去时,只需颠倒这个过程即可。
更详细一点可能如下:
在单元格中,我有一个容器视图,它是一个滚动视图(其用户交互通常被禁用)。
-
当用户点击它时,
创建一个新的透明背景视图,占据整个屏幕;
为该背景提供一个点击手势识别器,该识别器可以在稍后逆转该过程;
将单元格的容器视图从单元格移动到这个新的背景视图(使用convertRect
所以它还没有移动);
通过变换对容器的轻微收缩进行动画处理(一种微妙的效果,为您提供在视图上“下推”的效果);
-
在该动画的完成块中,启动一个新动画:
在我们的背景上设置一个点击手势的处理程序来逆转该过程。
Thus:
- (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];
}];
}];
}
正如您所知,这都是标准表视图等。如果您想使用视图控制器包含(例如,如果视图有大量的用户交互),您也可以这样做。它不会影响单元容器视图的增长/收缩方面的用户体验。
此外,这一切都不是自动布局的。您可以使用自动布局来做到这一点,但恕我直言,这更麻烦,因为您可能必须删除和添加约束,但肯定可以做到。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)