限定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手势,相当重要哦.

目录
相关文章
ViewPager 显示 两侧的View,各显示一点
ViewPager 显示 两侧的View,各显示一点
ViewPager 显示 两侧的View,各显示一点
|
iOS开发
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
iOS开发 - touchBegan事件判断点击的位置在View上还是在View的子View上
271 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的输出,发现了手势切换和自动切换的规律。
|
Java Android开发 Python
反射改变TabLayout属性
目录介绍 01.遇到的实际需求分析 02.原生TabLayout局限 03.TabLayout源码解析 3.1 Tab选项卡如何实现 3.2 滑动切换Tab选项卡 3.3 Tab选项卡指示线宽度 04.
1085 0
【JetPack】视图绑定 ( ViewBinding ) 各种应用 ( 视图绑定两种方式 | Activity 布局 | 对话框布局 | 自定义组件布局 | RecyclerView 列表布局 )
【JetPack】视图绑定 ( ViewBinding ) 各种应用 ( 视图绑定两种方式 | Activity 布局 | 对话框布局 | 自定义组件布局 | RecyclerView 列表布局 )
576 0
【JetPack】视图绑定 ( ViewBinding ) 各种应用 ( 视图绑定两种方式 | Activity 布局 | 对话框布局 | 自定义组件布局 | RecyclerView 列表布局 )
2-VIII--ViewPager滑动监听与自定义滑动特效
零、前言 [1]. 使用上文项目:1-VIII--ViewPager的基本使用 [2].对ViewPager的addOnPageChangeListener三个回调方法分析 [3].
1267 0
tablayout支持改变选中文字大小,支持左右滑动,支持viewpager,支持三角可移动指示器
TabLayout [简书地址] (https://www.jianshu.com/p/2c3f868266e8) 基于大神的FlycoTabLayout 传送地址和基本用法 用法和属性和这个库一样 效果图如下 Gif_20180828_142709.
2488 0