限定pan手势只能在圆内移动view

简介:

限定pan手势只能在圆内移动view

效果:

虽然看起来很简单,但实现原理还是稍微有点复杂-_-!!

核心的地方,就是需要计算pan手势的点与指定点的距离,不能超过这个距离,超过了就让动画还原,很容易理解:)

//
//  RootViewController.m
//  Circle
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"

@interface RootViewController ()

@end

@implementation RootViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 限定范围用的layer
    CALayer *circleLayer        = [CALayer layer];
    circleLayer.frame           = (CGRect){CGPointZero, CGSizeMake(250, 250)};
    circleLayer.position        = self.view.center;
    circleLayer.cornerRadius    = 250/2.f;
    circleLayer.opacity         = 0.5f;
    circleLayer.backgroundColor = [UIColor orangeColor].CGColor;
    [self.view.layer addSublayer:circleLayer];
    
    // 移动手势
    UIPanGestureRecognizer *pan = \
        [[UIPanGestureRecognizer alloc] initWithTarget:self
                                                action:@selector(gestureEvent:)];
    
    //  用于移动用的view
    UIView *move = [[UIView alloc] initWithFrame:(CGRect){CGPointZero, CGSizeMake(50, 50)}];
    move.backgroundColor    = [UIColor cyanColor];
    move.center             = self.view.center;
    move.layer.cornerRadius = 50/2.f;
    [move addGestureRecognizer:pan];
    [self.view addSubview:move];
}

- (void)gestureEvent:(UIPanGestureRecognizer *)gesture
{
    // 获取手势坐标点
    CGPoint translation = [gesture translationInView:gesture.view];
    
    // 开始
    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        [UIView animateWithDuration:0.2 animations:^{
            gesture.view.backgroundColor = [UIColor redColor];
        }];
    }
    
    // 状态改变
    if (gesture.state == UIGestureRecognizerStateChanged)
    {
        gesture.view.center = CGPointMake(gesture.view.center.x + translation.x,
                                          gesture.view.center.y + translation.y);

        // 计算手势的点与指定坐标的距离
        CGPoint pointA    = gesture.view.center;
        CGPoint pointB    = self.view.center;
        CGFloat distanceX = pointA.x - pointB.x;
        CGFloat distanceY = pointA.y - pointB.y;
        CGFloat distance  = sqrt(distanceX*distanceX + distanceY*distanceY);
        
        // 当距离在125.f以内时的一些操作
        if (distance <= 125.f)
        {
            [gesture setTranslation:CGPointZero
                             inView:gesture.view];
        }
        else
        {
            // 先关闭手势(不允许用户继续与手势交互)
            gesture.enabled = NO;
            
            [UIView animateWithDuration:0.2f animations:^{
                gesture.view.center          = self.view.center;
                gesture.view.backgroundColor = [UIColor cyanColor];
            } completion:^(BOOL finished) {
                // 动画结束后再次开启手势
                gesture.enabled = YES;
            }];
        }
    }
    
    // 结束
    if (gesture.state == UIGestureRecognizerStateEnded)
    {
        [UIView animateWithDuration:0.2f animations:^{
            gesture.view.center = self.view.center;
            gesture.view.backgroundColor = [UIColor cyanColor];
        }];
    }
}

@end

核心代码处:

1. 计算坐标值

2. 距离超出指定范围的时候就必须要关闭pan手势并执行动画,动画结束后再开启pan手势,相当重要哦.

目录
相关文章
|
小程序
小程序:picker-view选择器快速滚动,确认时,”值显示错误“
小程序:picker-view选择器快速滚动,确认时,”值显示错误“
362 0
|
iOS开发
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
290 0
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
|
前端开发 容器
View的测量、布局和绘制过程中父View(当前View)和子View的先后顺序
View的测量、布局和绘制过程中,到底是先测量(布局、绘制)父View,还是先测量子View,这篇文章会从源码角度给出答案。
ViewPager如何区分自动切换和手势滑动切换
ViewPager是一个很常见的组件,不仅支持收拾滑动切换页面,我们还可以通过`viewPager.setCurrentItem(index)`来切换到指定的页面,那么他们如何区分呢? 我们知道ViewPager可以添加`ViewPager.OnPageChangeListener`监听器,可以监听切换的状态。通过观察`ViewPager.OnPageChangeListener#onPageScrollStateChanged(int state)`方法中state的输出,发现了手势切换和自动切换的规律。
2-VIII--ViewPager滑动监听与自定义滑动特效
零、前言 [1]. 使用上文项目:1-VIII--ViewPager的基本使用 [2].对ViewPager的addOnPageChangeListener三个回调方法分析 [3].
1288 0
|
XML 前端开发 Android开发
|
Android开发
Android ImageView的scaleType(图片比例类型)属性与adjustViewBounds(调整视图边界)属性
本文转载自[Android ImageView的scaleType(图片比例类型)属性与adjustViewBounds(调整视图边界)属性]并做了排版的修改(http://www.
1187 0
|
Android开发
解析6种常用View 的滑动方法
  > View 的滑动是Android 实现自定义控件的基础,实现View 滑动有很多种方法,在这里主要讲解6 种滑动方法,分别是layout()、offsetLeftAndRight()与offsetTopAndBottom()、LayoutParams、动画、scollTo 与scollBy,以及Scroller。
1586 0

热门文章

最新文章