UI总结之cell之手势滑动
2015-09-28 20:39
531 查看
// 1. UIViewController #import "ViewController.h" #import "CustomCell.h" @interface ViewController () <UITableViewDataSource,UITableViewDelegate> @property (weak, nonatomic) IBOutlet UITableView *tableView; @property (nonatomic, strong) NSMutableArray *dataSourceArray; @end @implementation ViewController - (NSMutableArray *)dataSourceArray { if (_dataSourceArray == nil) { _dataSourceArray = [[NSMutableArray alloc] init]; for (int i = 0; i < 20; i++) { [_dataSourceArray addObject:[NSString stringWithFormat:@"name-%d",i+1]]; } } return _dataSourceArray; } - (void)viewDidLoad { [super viewDidLoad]; // 注册cell NSString *className = NSStringFromClass([CustomCell class]); [self.tableView registerClass:[CustomCell class] forCellReuseIdentifier:className]; // 设置cell的高度 这样直接设置会比起使用代理方法设置cell高度提高性能 self.tableView.rowHeight = 80.0f; } #pragma mark - - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.dataSourceArray count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *className = NSStringFromClass([CustomCell class]); CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:className forIndexPath:indexPath]; cell.name = [self.dataSourceArray objectAtIndex:indexPath.row]; // 取消选中样式 cell.selectionStyle = UITableViewCellSelectionStyleNone; // 设置按钮 [cell setActionButtonWithTitle:@"设置" direction:ActionButtonDirectionLeft actionButtonBlock:^(CustomCell *cell) { NSLog(@"设置"); }]; [cell setActionButtonWithTitle:@"删除" direction:ActionButtonDirectionRight actionButtonBlock:^(CustomCell *cell) { // 0. 根据cell获取当前的indexPath NSIndexPath *currentIndexPath = [tableView indexPathForCell:cell]; // 1. 删除数据源 [self.dataSourceArray removeObjectAtIndex:currentIndexPath.row]; // 2. 删除cell [tableView deleteRowsAtIndexPaths:@[currentIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; }]; // 这个块 是为了只让当前的cell显示 删除和设置按钮 [cell setBeginPanGestureActionBlock:^(CustomCell *cell){ // 当前屏幕上可以看到的cell NSIndexPath *indexPath_cell = [tableView indexPathForCell:cell]; for (CustomCell *visibleCell in [tableView visibleCells]) { NSIndexPath *indexPath_c = [tableView indexPathForCell:visibleCell]; // 判断cell的位置 需要判断section和row if (indexPath_c.section == indexPath_cell.section && indexPath_c.row == indexPath_cell.row) { // 不刷新 } else { // 刷新 [tableView reloadRowsAtIndexPaths:@[indexPath_c] withRowAnimation:UITableViewRowAnimationNone]; } } }]; return cell; }
// 2. CustomCell.h #import <UIKit/UIKit.h> // button的位置 typedef NS_ENUM(NSInteger, ActionButtonDirection) { /** 左边 */ ActionButtonDirectionLeft, /** 右边 */ ActionButtonDirectionRight, } ; @class CustomCell; // 按钮点击回调 typedef void(^ActionButtonBlock)(CustomCell *cell); // 开始拖动回调 typedef void(^BeginPanGestureActionBlock)(CustomCell *cell); @interface CustomCell : UITableViewCell /** cell的内容 */ @property (nonatomic,copy) NSString *name; /** * 设置按钮属性和回调事件等 * * @param title 按钮的标题 * @param direction 按钮的位置 是在左还是在右 * @param actionButtonBlock 按钮点击事件block回调 */ - (void)setActionButtonWithTitle:(NSString *)title direction:(ActionButtonDirection)direction actionButtonBlock:(ActionButtonBlock)actionButtonBlock; /** * 设置开始拖动的回调 */ - (void)setBeginPanGestureActionBlock:(BeginPanGestureActionBlock)beginPanGestureActionBlock; // CustomCell.m #import "CustomCell.h" /** 按钮的个数 */ #define kNumbersOfActionButton 2 /** 按钮高度 */ #define kActionButtonHeight self.contentView.frame.size.height /** 按钮宽度 */ #define kActionButtonWidth 120 /** 左边按钮tag */ #define kActionLeftButtonTag 2 /** 右边按钮tag */ #define kActionRightButtonTag 1 #define kAnimatedDuration 0.3f @interface CustomCell () <UIGestureRecognizerDelegate> /** 内容视图 */ @property (nonatomic, weak) UIView *cellContentView; @property (nonatomic, weak) UILabel *nameLabel; /** 删除按钮的block回调 */ @property (nonatomic, copy) ActionButtonBlock actionRightButtonBlock; /** 设置按钮的block回调 */ @property (nonatomic, copy) ActionButtonBlock actionLeftButtonBlock; /** 手势开始状态的block回调 */ @property (nonatomic, copy) BeginPanGestureActionBlock beginPanGestureActionBlock; @end @implementation CustomCell #pragma mark - 初始化操作 - (void)initViews { [self createActionButton]; [self addPanGestToCellContentView]; } // 创建cell的时候会走到这个方法 会调用这个方法屏幕 ‘cell数量+1’ 次 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { [self initViews]; } return self; } /** * 与 awakeFromNib 的区别 xib里面的子控件还没有创建出来 * 只用来初始化自身 */ - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self initViews]; } return self; } /** * 与 initWithCoder: 的区别 xib里面的子控件全都创建出来了 * 用来初始化子控件们 */ - (void)awakeFromNib { } #pragma mark - 懒加载 - (UIView *)cellContentView { if (_cellContentView == nil) { UIView *cellContentView = [[UIView alloc] init]; cellContentView.backgroundColor = [UIColor whiteColor]; [self.contentView addSubview:cellContentView]; _cellContentView = cellContentView; } return _cellContentView; } - (UILabel *)nameLabel { if (_nameLabel == nil) { UILabel *nameLabel = [[UILabel alloc] init]; [self.cellContentView addSubview:nameLabel]; nameLabel.backgroundColor = [UIColor orangeColor]; _nameLabel = nameLabel; } return _nameLabel; } #pragma mark - layout - (void)layoutSubviews { self.cellContentView.frame = self.contentView.bounds; self.nameLabel.frame = self.contentView.bounds; // 设置按钮的大小 for (int i = 0; i < kNumbersOfActionButton; i++) { UIButton *btn = (UIButton *)[self.contentView viewWithTag:i+1]; btn.frame = CGRectMake(self.frame.size.width-(i+1) *kActionButtonWidth, 0, kActionButtonWidth, kActionButtonHeight); } [super layoutSubviews]; } #pragma mark - GestureRecognizer - (void)addPanGestToCellContentView { UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestAction:)]; // 设置代理 pan.delegate = self; [self.cellContentView addGestureRecognizer:pan]; } - (void)panGestAction:(UIPanGestureRecognizer *)panGest { // 根据状态设置东西 当开始滑动手势的时候,需要刷新其余cell,只让当前cell 显示设置和删除按钮 if (panGest.state == UIGestureRecognizerStateBegan) { // 手势开始 if (_beginPanGestureActionBlock) { _beginPanGestureActionBlock(self); } } else if (panGest.state == UIGestureRecognizerStateChanged) { // 手势移动 CGPoint point = [panGest translationInView:self.contentView]; // 修改中心点坐标 CGFloat centerX = self.cellContentView.center.x + point.x; // 情况1. 刚开始 直接右滑 if (centerX > self.contentView.center.x) { centerX = self.contentView.center.x; self.cellContentView.center = CGPointMake(centerX, self.cellContentView.center.y); } // 情况2. 按钮显示 右滑 if ((point.x > 0 && self.cellContentView.center.x < self.contentView.center.x)) { self.cellContentView.center = CGPointMake(centerX, self.cellContentView.center.y); } // 情况3. 删除按钮显示不完全,回弹 if (centerX < self.contentView.center.x && centerX > self.contentView.center.x - kActionButtonWidth) { self.cellContentView.center = CGPointMake(centerX, self.cellContentView.center.y); } // 情况4. 删除按钮显示完全 if (centerX < self.contentView.center.x-kActionButtonWidth && centerX > self.contentView.center.x-kActionButtonWidth*kNumbersOfActionButton) { self.cellContentView.center = CGPointMake(centerX, self.cellContentView.center.y); } // translation需要归0因为是不断增加的。 [panGest setTranslation:CGPointZero inView:self.cellContentView]; } else if (panGest.state == UIGestureRecognizerStateEnded) { // 手势结束 if (self.cellContentView.center.x > self.contentView.center.x - kActionButtonWidth && self.cellContentView.center.x < self.contentView.center.x) { [UIView animateWithDuration:kAnimatedDuration animations:^{ self.cellContentView.center = CGPointMake(self.contentView.center.x, self.cellContentView.center.y); }]; } if ((self.cellContentView.center.x < (self.contentView.center.x-kActionButtonWidth)) && (self.cellContentView.center.x > (self.contentView.center.x-kActionButtonWidth*kNumbersOfActionButton))) { [UIView animateWithDuration:kAnimatedDuration animations:^{ self.cellContentView.center = CGPointMake(self.contentView.center.x-kActionButtonWidth*kNumbersOfActionButton, self.cellContentView.center.y); }]; } b719 } } #pragma mark - 按钮 - (void)setActionButtonWithTitle:(NSString *)title direction:(ActionButtonDirection)direction actionButtonBlock:(ActionButtonBlock)actionButtonBlock { NSInteger tag = kActionLeftButtonTag; // 如果是右按钮 if (direction == ActionButtonDirectionRight) { tag = kActionRightButtonTag; _actionRightButtonBlock = actionButtonBlock; } else { _actionLeftButtonBlock = actionButtonBlock; } UIButton *btn = (UIButton *)[self.contentView viewWithTag:tag]; [btn setTitle:title forState:UIControlStateNormal]; } - (void)setBeginPanGestureActionBlock:(BeginPanGestureActionBlock)beginPanGestureActionBlock { _beginPanGestureActionBlock = beginPanGestureActionBlock; } - (void)createActionButton { for (int i = 0; i < kNumbersOfActionButton; i++) { UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; [self.contentView addSubview:btn]; if (i == 0) { // 如果是右边按钮 btn.backgroundColor = [UIColor redColor]; btn.tag = kActionRightButtonTag; } else { // 如果是左边按钮 btn.backgroundColor = [UIColor lightGrayColor]; btn.tag = kActionLeftButtonTag; } [btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside]; } } - (void)btnAction:(UIButton *)btn { if (btn.tag == kActionLeftButtonTag && _actionLeftButtonBlock) { _actionLeftButtonBlock(self); } if (btn.tag == kActionRightButtonTag && _actionRightButtonBlock) { _actionRightButtonBlock(self); } } #pragma mark - setter - (void)setName:(NSString *)name { _name = [name copy]; self.nameLabel.text = _name; } #pragma mark - 手势代理方法 /** * 通过此代理方法实现 上下拖动和左右拖动的区分 * 如果 左右拖动幅度 大于 上下拖动幅度 */ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer; CGPoint point = [pan translationInView:self.contentView]; // 左右滑动 if (fabs(point.x) > fabs(point.y)) { return YES; } } return NO; }
相关文章推荐
- [APUE]再读之高级IO
- UI 第1讲 UIView
- How to Read and Understand a Scientific Paper: A Step-by-Step Guide for Non-Scientists
- druid 配置_StatFilter
- iOS界面编程-UILabel
- Android 自己的自动化测试(4)<uiautomator>
- DruidDataSource配置
- 文本框 UITextView
- OS开发UI篇—UITableviewcell的性能问题
- iOS开发UI篇—UITableview控件基本使用
- iOS开发UI篇—UITableview控件简单介绍
- IOS开发UI篇—UIScrollView控件实现图片缩放功能
- UITableView的搜索功能8.0以前版本
- iOS开发UI篇—UIScrollView控件介绍
- OS开发UI篇—iOS开发中三种简单的动画设置
- OS开发UI篇—IOS开发中Xcode的一些使用技巧
- UIScrollView(滚动视图)和(UIPageController)页面控制器+ 定时器的使用
- UITableView实现类似QQ好友的折叠功能
- 搜索栏的使用(UISearchBar)(跳转到下一个页面,搜索栏消失)
- ueditor使用