通过 UIPanGestureRecognizer 手势来控制侧拉view的显示
在QHLViewController.m文件中,先添加一些宏定义和参数等等。
#define QHLAnimatingDuration 0.5 #define QHLMainViewMaxOffsetX 250 #define QHLLeftViewOriginX -50 typedef enum{ QHLViewControllerStateClosed = 0, QHLViewControllerStateOpening, QHLViewControllerStateOpened, QHLViewControllerStateClosing }QHLViewControllerState; @interface QHLViewController ()<UITableViewDataSource> @property (nonatomic, assign) CGPoint point; @property (nonatomic, assign) CGPoint location; @property (nonatomic, strong) UIView *leftV; @property (nonatomic, strong) UIView *mainV; @property (nonatomic, strong) UITapGestureRecognizer *tapGesTureR; @property (nonatomic, strong) UIPanGestureRecognizer *panGesTureR; @property (nonatomic, assign) QHLViewControllerState state; @end
在viewWillAppear:(BOOL)animated方法中,创建需要的leftV和mainV这两个view
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //创建并设置leftV的属性 UITableView *leftV = [[UITableView alloc] initWithFrame:CGRectMake(QHLLeftViewOriginX, 0, self.view.bounds.size.width, self.view.bounds.size.height)]; leftV.backgroundColor = [UIColor whiteColor]; leftV.dataSource = self; self.leftV = leftV; [self.view addSubview:leftV]; //创建并设置mainView的属性 UIView *mainV = [[UIView alloc] initWithFrame:self.view.bounds]; mainV.backgroundColor = [UIColor purpleColor]; self.mainV = mainV; [self.view addSubview:mainV]; }
在viewDidLoad中先设置自身的状态为关闭,创建拖动和点击的手势,并且先添加拖动手势到控制器
- (void)viewDidLoad { [super viewDidLoad]; //设置默认状态下自身控制器的state状态 self.state = QHLViewControllerStateClosed; //添加拖动手势 self.panGesTureR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(observePanGestureRecognizer:)]; [self.view addGestureRecognizer:self.panGesTureR]; //设置点击手势 self.tapGesTureR =[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(observeTapGesTureRecognizer:)]; }
根据手势的不同状态来实现手势的触发方法,在不同手势状态下,给自身设置不同的state。
/** * 拖动手势的实现方法 */ - (void)observePanGestureRecognizer:(UIPanGestureRecognizer *)panGestureRecognizer { //获取当前拖动手势的状态 UIGestureRecognizerState state = panGestureRecognizer.state; CGPoint location = [panGestureRecognizer locationInView:self.view]; //位置 CGRect main = self.mainV.frame; CGRect left = self.leftV.frame; switch (state) { //手势开始时候 case UIGestureRecognizerStateBegan: //获取开始位置的point self.point = location; //根据手势触发之前的自身状态来设置现在的状态 if (self.state == QHLViewControllerStateClosed) { self.state = QHLViewControllerStateOpening; //opening } else { self.state = QHLViewControllerStateClosing; //closing } break; //手势变化时候 case UIGestureRecognizerStateChanged: { //偏移量x CGFloat offsetX = 0; //下面2种情况,offsetX都是大于等于0的 if (self.state == QHLViewControllerStateOpening) { //此时自身状态只有QHLViewControllerStateOpening和QHLViewControllerStateClosing offsetX = location.x - self.point.x; } else { offsetX = QHLMainViewMaxOffsetX - (self.point.x - location.x); } if (offsetX > QHLMainViewMaxOffsetX) { left.origin.x = 0; main.origin.x = QHLMainViewMaxOffsetX; } else if (offsetX < 0) { left.origin.x = QHLLeftViewOriginX; main.origin.x = 0; }else { main.origin.x = offsetX; left.origin.x = QHLLeftViewOriginX - offsetX * QHLLeftViewOriginX / QHLMainViewMaxOffsetX; } self.mainV.frame = main; self.leftV.frame = left; break; } //手势结束时候 case UIGestureRecognizerStateEnded: { //结束之前的那一刻,只会有2种状态 QHLViewControllerStateOpening 和 QHLViewControllerStateClosing CGFloat endX = main.origin.x; if (self.state == QHLViewControllerStateOpening) { // x 取值 >= 0 if (endX == QHLMainViewMaxOffsetX) { // 结束时候的 x 取最大值 self.state = QHLViewControllerStateOpened; } else if (endX > QHLMainViewMaxOffsetX / 2) { // 结束时候的 x 大于 最大值的 1/2 [self animatingOpen]; } else { // 结束时候的 x 小于 最大值的 1/2 [self animatingClose]; } } else { // x 取值 0 ~ 250 if (endX > QHLMainViewMaxOffsetX / 2) { [self animatingOpen]; } else { [self animatingClose]; } } break; } } }
点击手势要等mainV偏移量达到最大的时候才添加进去!!!
/** * 点击手势的实现方法 */ - (void)observeTapGesTureRecognizer:(UITapGestureRecognizer *)tapGestureRecognizer { [UIView animateWithDuration:QHLAnimatingDuration animations:^{ self.mainV.frame = [UIScreen mainScreen].bounds; self.leftV.frame = CGRectMake(QHLLeftViewOriginX, 0, self.view.frame.size.width, self.view.frame.size.height); } completion:^(BOOL finished) { self.state = QHLViewControllerStateClosed; }]; }
当mainV的偏移量达到一定要求后就会调用下面2个方法
当以动画形式打开 在完成时候,添加点击手势
当以动画形式关闭 在完成时候,移除点击手势
/** * 以动画形式打开 */ - (void)animatingOpen { CGRect main = self.mainV.frame; [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:0.7 options:UIViewAnimationOptionAllowAnimatedContent animations:^{ self.mainV.frame = CGRectMake(QHLMainViewMaxOffsetX, 0, main.size.width, main.size.height); self.leftV.frame = self.view.bounds; } completion:^(BOOL finished) { //设置state状态 self.state = QHLViewControllerStateOpened; //添加点击手势 [self.mainV addGestureRecognizer:self.tapGesTureR]; }]; } /** * 以动画形式关闭 */ - (void)animatingClose { CGRect main = self.mainV.frame; [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:1.0 initialSpringVelocity:0.7 options:UIViewAnimationOptionAllowAnimatedContent animations:^{ self.mainV.frame = self.view.bounds; self.leftV.frame =CGRectMake(QHLLeftViewOriginX, 0, main.size.width, main.size.height); } completion:^(BOOL finished) { //设置state状态 self.state = QHLViewControllerStateClosed; //移除点击手势 [self.mainV removeGestureRecognizer:self.tapGesTureR]; }]; }
侧拉leftV的dataSource方法
#pragma mark - table view delegate & data source - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 5; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *ID = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; } cell.textLabel.text = [NSString stringWithFormat:@"Message - %ld",(long)indexPath.row]; return cell; }
对于QQ左上角按钮点击之后弹出的设置页面 导航控制器的bar和底部的tabBar会跟随着移动,有知道的大牛给点思路!!!!
渣渣已经脑细胞死光了v_v