温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

iOS自定义View如何实现卡片滑动

发布时间:2021-05-24 11:22:31 来源:亿速云 阅读:219 作者:小新 栏目:移动开发

这篇文章给大家分享的是有关iOS自定义View如何实现卡片滑动的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

说明

控件基于UIView封装完成,采用UIPanGestureRecognizer监听自身的触摸事件,以此处理各种滑动动画操作。
内容之间可以循环切换,采用类似tableView加载机制,达到复用效果

效果

iOS自定义View如何实现卡片滑动

代码实现

#import <UIKit/UIKit.h> @class SMSwipeView; @protocol SMSwipeDelegate <NSObject> @required //获取显示数据内容 -(UITableViewCell*)SMSwipeGetView:(SMSwipeView*)swipe withIndex:(int)index; //获取数据源总量 -(NSInteger)SMSwipeGetTotaleNum:(SMSwipeView*)swipe; @end @interface SMSwipeView : UIView @property(nonatomic,weak)id<SMSwipeDelegate> delegate; //层叠透明方式显示 默认NO @property(nonatomic,assign)BOOL isStackCard; //加载方法 -(void)reloadData; //根据id获取缓存的cell -(UITableViewCell*)dequeueReusableUIViewWithIdentifier:(NSString*)identifier; @end
#import "SMSwipeView.h" #define degreeTOradians(x) (M_PI * (x)/180) //childView距离父View左右的距离 const int LEFT_RIGHT_MARGIN=10; //当前view距离父view的顶部的值 const int TOP_MARGTIN=16; @interface SMSwipeView() //已经划动到边界外的一个view @property(nonatomic,weak)UITableViewCell * viewRemove; //放当前显示的子View的数组 @property(nonatomic,strong)NSMutableArray * cacheViews; //view总共的数量 @property(nonatomic,assign)int totalNum; //当前的下标 @property(nonatomic,assign)int nowIndex; //触摸开始的坐标 @property(nonatomic,assign)CGPoint pointStart; //上一次触摸的坐标 @property(nonatomic,assign)CGPoint pointLast; //最后一次触摸的坐标 @property(nonatomic,assign)CGPoint pointEnd; //正在显示的cell @property(nonatomic,weak)UITableViewCell * nowCell; //下一个cell @property(nonatomic,weak)UITableViewCell * nextCell; //第三个cell @property(nonatomic,weak)UITableViewCell * thirdCell; //自身的宽度 @property(nonatomic,assign)int w; //自身的高度 @property(nonatomic,assign)int h; //是否是第一次执行 @property(nonatomic,assign)BOOL isFirstLayoutSub; @end @implementation SMSwipeView //从xib中加载该类 -(void)awakeFromNib{  [super awakeFromNib];  [self initSelf]; } //直接用方法初始化 -(instancetype)initWithFrame:(CGRect)frame{  self=[super initWithFrame:frame];  [self initSelf];  return self; } //进行一些自身的初始化和设置 -(void)initSelf{  self.clipsToBounds=YES;  self.cacheViews=[[NSMutableArray alloc]init];  //手势识别  UIPanGestureRecognizer * pan=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];  [self addGestureRecognizer:pan]; } //布局subview的方法 -(void)layoutSubviews{  if(!self.isFirstLayoutSub){  self.isFirstLayoutSub=YES;  self.w=self.bounds.size.width;  self.h=self.bounds.size.height;  [self reloadData];  } } //重新加载数据方法,会再首次执行layoutSubviews的时候调用 -(void)reloadData{  if (!self.delegate||![self.delegate respondsToSelector:@selector(SMSwipeGetView:withIndex:)]||![self.delegate respondsToSelector:@selector(SMSwipeGetTotaleNum:)]) {  return;  }  self.totalNum=(int)[self.delegate SMSwipeGetTotaleNum:self];  self.viewRemove=nil;  UITableViewCell * nowCell=[self.delegate SMSwipeGetView:self withIndex:self.nowIndex];  UITableViewCell * nextCell=[self.delegate SMSwipeGetView:self withIndex:self.nowIndex+1<self.totalNum?self.nowIndex+1:0];  UITableViewCell * thirdCell=[self.delegate SMSwipeGetView:self withIndex:self.nowIndex+2<self.totalNum?self.nowIndex+2:self.nowIndex+2-self.totalNum];  if (self.isStackCard) {  [thirdCell setAlpha:0.3f];  [nextCell setAlpha:0.5f];  [nowCell setAlpha:1];  }  [thirdCell removeFromSuperview];  thirdCell.layer.anchorPoint=CGPointMake(1, 1);  thirdCell.frame=CGRectMake(LEFT_RIGHT_MARGIN*2, 0, self.w-2*2*LEFT_RIGHT_MARGIN, self.h-TOP_MARGTIN);  [self addSubview:thirdCell];  self.thirdCell=thirdCell;  [nextCell removeFromSuperview];  nextCell.layer.anchorPoint=CGPointMake(1, 1);  nextCell.frame=CGRectMake(LEFT_RIGHT_MARGIN, TOP_MARGTIN/2*1, self.w-2*LEFT_RIGHT_MARGIN, self.h-TOP_MARGTIN);  [self addSubview:nextCell];  self.nextCell=nextCell;  [nowCell removeFromSuperview];  nowCell.layer.anchorPoint=CGPointMake(1, 1);  nowCell.frame=CGRectMake(0, TOP_MARGTIN, self.w, self.h-TOP_MARGTIN);  [self addSubview:nowCell];  self.nowCell=nowCell; } #pragma mark swipe触摸的相关手势处理 -(void)swipe:(UISwipeGestureRecognizer*)sender{  NSLog(@"swipe"); } -(void)pan:(UIPanGestureRecognizer*)sender{  CGPoint translation = [sender translationInView: self];  //CGPoint speed=[sender velocityInView:self];//获取速度  if (sender.state==UIGestureRecognizerStateBegan) {  //NSLog(@"begin");  self.pointStart=translation;  self.pointLast=translation;  }  if (sender.state==UIGestureRecognizerStateChanged) {  //NSLog(@"change");  // CGFloat xMove=translation.x-self.pointLast.x;  // CGFloat yMove=translation.y-self.pointLast.y;  // self.pointLast=translation;  //  // CGPoint center=self.nowCell.center;  // self.nowCell.center=CGPointMake(center.x+xMove, center.y+yMove);  CGFloat xTotalMove=translation.x-self.pointStart.x;  // if (xTotalMove<0) {  //  self.nowCell.transform = CGAffineTransformMakeRotation(degreeTOradians(90*xTotalMove/self.w));  //  self.nextCell.transform= CGAffineTransformMakeRotation(degreeTOradians(90*xTotalMove/self.w/2));  // }else{  //  self.nowCell.transform = CGAffineTransformMakeRotation(degreeTOradians(0));  //  self.nextCell.transform= CGAffineTransformMakeRotation(degreeTOradians(0));  // }  }  if (sender.state==UIGestureRecognizerStateEnded) {  //NSLog(@"end");  CGFloat xTotalMove=translation.x-self.pointStart.x;  if (xTotalMove<0) {   [self swipeEnd];  }else{   [self swipeGoBack];  }  }  // NSLog(@"%@%f%@%f",@"x:",speed.x,@"y:",speed.y);  //NSLog(@"%@%f%@%f",@"x:",translation.x,@"y:",translation.y); } /**  * @author StoneMover, 16-12-29 14:12:33  *  * @brief 获取为显示的cell,复用机制  *  * @param identifier id标志  *  * @return 返回的cell,如果缓存中没有则返回空  */ -(UITableViewCell*)dequeueReusableUIViewWithIdentifier:(NSString *)identifier{  for (UITableViewCell * cell in self.cacheViews) {  if ([identifier isEqualToString:cell.reuseIdentifier]) {   [self.cacheViews removeObject:cell];   return cell;  }  }  return nil; } //滑动到下一个界面 -(void)swipeEnd{  [UIView animateWithDuration:0.3 animations:^{  self.nextCell.transform= CGAffineTransformMakeRotation(degreeTOradians(0));  }];  //self.nowCell.transform= CGAffineTransformMakeRotation(degreeTOradians(0));  CGPoint center=self.nowCell.center;  [UIView animateWithDuration:0.3 animations:^{  self.nowCell.center=CGPointMake(center.x-self.w, center.y);  self.nowCell.transform= CGAffineTransformMakeRotation(degreeTOradians(0));  // [self.nowCell setAlpha:0.0];  } completion:^(BOOL finished) {  self.nowIndex++;  self.nowIndex=self.nowIndex<self.totalNum?self.nowIndex:0;  if (self.viewRemove&&[self isNeedAddToCache:self.viewRemove]) {   [self.cacheViews addObject:self.viewRemove];   [self.viewRemove removeFromSuperview];  }  self.viewRemove=self.nowCell;  //self.viewRemove.layer.anchorPoint=CGPointMake(0, 0);  //self.viewRemove.transform=CGAffineTransformMakeRotation(degreeTOradians(-35));  self.nowCell=self.nextCell;  self.nextCell=self.thirdCell;  UITableViewCell * thirdCell=[self.delegate SMSwipeGetView:self withIndex:self.nowIndex+2<self.totalNum?(int)self.nowIndex+2:(int)self.nowIndex+2-(int)self.totalNum];  [thirdCell removeFromSuperview];  thirdCell.layer.anchorPoint=CGPointMake(1, 1);  thirdCell.frame=CGRectMake(LEFT_RIGHT_MARGIN*2, 0, self.w-2*2*LEFT_RIGHT_MARGIN, self.h-TOP_MARGTIN);  self.thirdCell=thirdCell;  if (self.isStackCard) {   [self.thirdCell setAlpha:0.3f];   [self.nextCell setAlpha:0.5f];   [self.nowCell setAlpha:1];  }  [self insertSubview:thirdCell belowSubview:self.nextCell];  [UIView animateWithDuration:0.2 animations:^{   self.nowCell.frame=CGRectMake(0, TOP_MARGTIN, self.w, self.h-TOP_MARGTIN);   self.nextCell.frame=CGRectMake(LEFT_RIGHT_MARGIN, TOP_MARGTIN/2*1, self.w-2*LEFT_RIGHT_MARGIN, self.h-TOP_MARGTIN);  }];  }]; } //滑动到上一个界面 -(void)swipeGoBack{  if (!self.viewRemove) {  NSLog(@"!viewRemove");  return;  }  if (self.nowIndex==0) {  NSLog(@"!viewRemove+index");  return;  }  CGPoint center=self.viewRemove.center;  self.nowIndex--;  // if ([self isNeedAddToCache:self.thirdCell]) {  // [self.cacheViews addObject:self.thirdCell];  // }  [self.thirdCell removeFromSuperview];  self.thirdCell=self.nextCell;  self.nextCell=self.nowCell;  self.nowCell=self.viewRemove;  if (self.nowIndex==0) {  self.viewRemove=nil;  }else{  UITableViewCell * cell=[self.delegate SMSwipeGetView:self withIndex:(int)self.nowIndex-1];  [cell removeFromSuperview];  [self insertSubview:cell aboveSubview:self.nowCell];  cell.layer.anchorPoint=CGPointMake(1, 1);  cell.frame=self.viewRemove.frame;  self.viewRemove=cell;  }  [UIView animateWithDuration:.5 animations:^{  self.nowCell.center=CGPointMake(center.x+self.w, center.y);  self.nowCell.transform= CGAffineTransformMakeRotation(degreeTOradians(0));  self.nextCell.frame=CGRectMake(LEFT_RIGHT_MARGIN, TOP_MARGTIN/2*1, self.w-2*LEFT_RIGHT_MARGIN, self.h-TOP_MARGTIN);  self.thirdCell.frame=CGRectMake(LEFT_RIGHT_MARGIN*2, 0, self.w-2*2*LEFT_RIGHT_MARGIN, self.h-TOP_MARGTIN);  }]; } //是否需要加入到缓存中去 -(BOOL)isNeedAddToCache:(UITableViewCell*)cell{  for (UITableViewCell * cellIn in self.cacheViews) {  if ([cellIn.reuseIdentifier isEqualToString:cell.reuseIdentifier]) {   return NO;  }  }  return YES; } @end

感谢各位的阅读!关于“iOS自定义View如何实现卡片滑动”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI