正如已经指出的,有很多方法可以实现这个 UI,但一种方法是从 tableview 单元格中获取视图,将其移动到一些新的背景上,然后更改它的框架。当你把它放回去时,只需反转这个过程。
更详细一点,可能如下:
在单元格中,我有一个容器视图,它是一个滚动视图(其用户交互通常被禁用)。
当用户点击它时,
创建一个占据整个屏幕的透明背景视图;
为该背景提供一个轻击手势识别器,该识别器可以在以后反转该过程;
将单元格的容器视图从单元格移动到这个新的背景视图(使用convertRect
所以它还没有移动);
通过变换对容器的轻微收缩进行动画处理(一种微妙的效果,让您有“下推”视图的效果);
在该动画的完成块中,启动一个新动画:
在我们的背景上为点击手势设置一个处理程序,以反转该过程。
因此:
- (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];
}];
}];
}
如您所知,这是所有标准表格视图等。如果您想使用视图控制器包含(例如,如果视图具有重要的用户交互),您也可以这样做。就单元格的容器视图的增长/缩小而言,它不会影响用户体验。
此外,这一切都是非自动布局。您可以使用自动布局来做到这一点,但更麻烦的是,恕我直言,因为您可能必须删除和添加约束,但肯定可以做到。