iOS 抽屉式效果列表

之前很喜欢收藏dribbble里面的一些动效gif,里面不仅是动效还是配色等等都非常的美,作为一个视觉动物,真的想把他们一个一个都实现出来,作为自己的一个作品,那真的是一件赏心悦目的事情,看着G20也快结束了,赶紧趁还闲着,先实现一个,我先挑选了一个比较简单的动效-----抽屉式效果列表
我们先来看下效果:

iOS 抽屉式效果列表_第1张图片

原来的动效地址找不到了...有知道的请留言给我...
代码地址:https://github.com/Yuzeyang/GCDrawerTableView
老样子,我们来分析下步骤

0x00 cell的处理

我们将cell详情界面分开来处理,我们可以看到,当我们选中其中一个cell的时候,该cell会移动到列表上方的某一个位置,其他cell则不显示,点击x的时候,cell返回为原位,其他cell又重新显示

选中处理:首先是先将其他cell隐藏,我们取出tableview的可见cell,然后将除了选中的cell之外的透明度都设置为0

GCTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

[self.tableView bringSubviewToFront:cell];

for (UIView *subcell in tableView.visibleCells) {
   if (subcell != cell) {
       subcell.alpha = 0;
   }

}

然后改变选中cell的原点值,并且给cell增加阴影,这里我偷懒没有做按钮的动画,只是用文字表示了按钮的状态

[UIView animateWithDuration:0.3 animations:^{

   CGRect rect = self.frame;

   self.originCellFrame = rect;
   CGPoint origin = CGPointMake(0, contentOffsetY + 30);
   rect.origin = origin;
   self.frame = rect;
​
   // 详情页处理
​

   [self addShadowWithView:self];

   [self addShadowWithView:self.detailView];

   [self.detailButton setTitle:@"×" forState:UIControlStateNormal];
}];

由于cell的动画处理是放在自定义cell里面做的,所以在点击关闭的时候,需要在动画结束之后回调给视图控制器,所以这里就用了block来回调关闭的状态

- (void)deselectCell {

   [UIView animateWithDuration:0.3 animations:^{
       self.frame = self.originCellFrame;
       
       self.layer.shadowColor = [UIColor clearColor].CGColor;
       self.layer.shadowRadius = 0;
       self.layer.shadowOpacity = 0.0;
       
       // 详情页处理

       [self.detailButton setTitle:@"..." forState:UIControlStateNormal];
   } completion:^(BOOL finished) {
       [self.helperHideView removeFromSuperview];
       [self.detailView removeFromSuperview];
       if (_deselectBlock) {
           _deselectBlock();
       }
   }];
}

然后在试图控制器里面,将其他的cell透明度改成1

[cell addDeselectBlock:^() {

   for (UIView *subcell in tableView.visibleCells) {

       if (subcell != cell) {

           subcell.alpha = 1;
       }
   }
   tableView.allowsSelection = YES;
   tableView.scrollEnabled = YES;
}];

0x01 详情页

可以看到详情页是类似于从上掉落的感觉,可能会联想到电商的那些筛选栏,但是筛选栏点击的时候,是上部分开始出现一直到下面,展示的顺序是反过来的,后面想了很久,只能想到利用视觉错误的效果,将详情页添加到cell的下一层,然后cell动画时候,详情页也做相应的动画,但是由于详情页的sizecell肯定是要大的,所以如果加到cell下一层时,是遮挡不住的,所以就需要一个遮挡的view来遮住详情页

首先我们需要将cell移到最前

[self.tableView bringSubviewToFront:cell];

然后在cell的下一层加上遮挡视图详情页,并根据cell的origin做frame的变化

UIView *superview = self.superview;

   
CGFloat height = CGRectGetMinY(self.frame) - contentOffsetY + 30;

[self.helperHideView setFrame:CGRectMake(0, contentOffsetY, CGRectGetWidth(self.frame), height)];

[superview insertSubview:self.helperHideView belowSubview:self];
​
[self.detailView setFrame:CGRectMake(0, CGRectGetMaxY(self.frame) - (GCDeviceHeight - 100 - 30*2),
                                     CGRectGetWidth(self.frame), GCDeviceHeight - 100 - 30*2)];
[superview insertSubview:self.detailView belowSubview:self.helperHideView];
​
[UIView animateWithDuration:0.3 animations:^{
  // cell处理 

 

  CGRect rect2 = self.helperHideView.frame;

   self.originHelperViewFrame = rect2;
   CGPoint origin2 = CGPointMake(0, contentOffsetY + 30 - height);
   rect2.origin = origin2;
   self.helperHideView.frame = rect2;
​
   CGRect rect1 = self.detailView.frame;
   self.originDetailViewFrame = rect1;
   CGPoint origin1 = CGPointMake(0, 100 + 30 + contentOffsetY);
   rect1.origin = origin1;
   self.detailView.frame = rect1;
​
   [self addShadowWithView:self];
   [self addShadowWithView:self.detailView];
   [self.detailButton setTitle:@"×" forState:UIControlStateNormal];
}];

然后在关闭的时候,移除掉

- (void)deselectCell {

   [UIView animateWithDuration:0.3 animations:^{
       // cell处理

       
       self.detailView.layer.shadowColor = [UIColor clearColor].CGColor;
       self.detailView.layer.shadowRadius = 0;
       self.detailView.layer.shadowOpacity = 0.0;
       
       self.detailView.frame = self.originDetailViewFrame;
       self.helperHideView.frame = self.originHelperViewFrame;
       
       [self.detailButton setTitle:@"..." forState:UIControlStateNormal];
   } completion:^(BOOL finished) {
       [self.helperHideView removeFromSuperview];
       [self.detailView removeFromSuperview];
       if (_deselectBlock) {
           _deselectBlock();
       }
   }];
}

这样就实现了抽屉式的效果,但是总感觉还有更好的办法实现,如果有思路的,欢迎交流~

你可能感兴趣的:(iOS 抽屉式效果列表)