手势简单应用

  • 两指缩放
  • 上下滑动可以改变笑脸弧度

@IBDesignable 使View可以在storyBoard中实时预览

@IBInspectable 使属性可以在storyBoard中设置

HappinessViewController.swift

import UIKit

public class HappinessViewController: UIViewController ,FaceViewDataSource{

    var happiness:Int = 25 {  //0 = vary sad,100 = ecstatic
            didSet{
                happiness = min(max(happiness,0),100)
                println("happiness = \(happiness)")
                updateUI()
            }
    }

    private struct Constants{
        static let HappinessGestureScale:CGFloat = 4
    }

    // 滑动的事件
    @IBAction func changeHappiness(gesture: UIPanGestureRecognizer) {
        switch gesture.state{
        case .Ended:fallthrough
        case .Changed:
            let translation =
                gesture.translationInView(faceView)
            let happinessChange = -Int(translation.y / Constants.HappinessGestureScale)

            if happiness != 0 {
                happiness += happinessChange
                gesture.setTranslation(CGPointZero, inView: faceView)
            }

        default :break
        }
    }

    @IBOutlet weak var faceView: FaceUIView!{
        didSet{
            faceView.dataSource  = self
            // 添加缩放事件,调用的是daceView里面的scale方法
            faceView.addGestureRecognizer(UIPinchGestureRecognizer(target: faceView, action: "scale:"))
//            faceView.addGestureRecognizer(UIPanGestureRecognizer(target: faceView, action: "scale:"))
        }
    }

    private func updateUI(){
        faceView.setNeedsDisplay()
    }

    func smilinessForFaceView(sender:FaceUIView) -> Double?{
        return Double(happiness-50)/50
    }
}

FaceUIView.swift

import UIKit

protocol FaceViewDataSource :class{
    func smilinessForFaceView(sender: FaceUIView) -> Double?
}

@IBDesignable
class FaceUIView: UIView {

    // @IBInspectable 使属性可以在storyBoard中设置
    @IBInspectable
     var lineWidth:CGFloat = 3{didSet{setNeedsDisplay()}}
    @IBInspectable var color:UIColor = UIColor.blueColor() { didSet{setNeedsDisplay() } }
    @IBInspectable var scale:CGFloat = 0.90{didSet { setNeedsDisplay() } }

    var faceCenter:CGPoint{return convertPoint(center,fromView:superview)}
    // 笑脸的半径
    var faceRadius:CGFloat {
        return min(bounds.size.width, bounds.size.height) / 2 * scale
    }

    weak var dataSource: FaceViewDataSource?

    // 缩放
    func scale(gesture:UIPinchGestureRecognizer){
        if gesture.state == .Changed{
            scale *= gesture.scale
            gesture.scale = 1
        }
    }

    override func drawRect(rect: CGRect) {
        let facePath = UIBezierPath(arcCenter: faceCenter, radius: faceRadius, startAngle: 0, endAngle:CGFloat(2 * M_PI), clockwise: true)

        facePath.lineWidth = lineWidth
        color.set()
        facePath.stroke()

        bezierPathForEye(.Left).stroke()
        bezierPathForEye(.Right).stroke()

        // 此处改变笑脸弧度
        let smiliness = dataSource?.smilinessForFaceView(self) ?? 0.0
        let smilePath = bezierPathForSmile(smiliness)
        smilePath.stroke()
    }

    private struct Scaling {
        static let FaceRadiusToEyeRadiusRatio:CGFloat = 10
        static let FaceRadiusToEyeOffsetRatio:CGFloat = 3
        static let FaceRadiusToEyeSeparationRatio:CGFloat = 1.5
        static let FaceRadiusToMouthWidthRatio:CGFloat = 1
        static let FaceRadiusToMouthHeightRatio:CGFloat = 3
        static let FaceRadiusToMouthOffsetRatio:CGFloat = 3
    }
    private enum Eye {case Left,Right}

    // 画眼睛
    private func bezierPathForEye(whichEye:Eye) -> UIBezierPath{
        let eyeRadius = faceRadius / Scaling.FaceRadiusToEyeRadiusRatio
        let eyeVerticaloffset = faceRadius / Scaling.FaceRadiusToEyeOffsetRatio
        let eyeHorizontalSeparation = faceRadius / Scaling.FaceRadiusToEyeSeparationRatio

        var eyeCenter = faceCenter
        eyeCenter.y -= eyeVerticaloffset

        switch whichEye {
        case .Left: eyeCenter.x -= eyeHorizontalSeparation / 2
        case .Right: eyeCenter.x += eyeHorizontalSeparation / 2
        default :break
        }

        let path = UIBezierPath(arcCenter: eyeCenter, radius: eyeRadius, startAngle: 0, endAngle:CGFloat(2*M_PI), clockwise: true)

        path.lineWidth = lineWidth
        return path
    }

    // 画嘴角弧度
    private func bezierPathForSmile(fractionOfmaxSmile:Double ) -> UIBezierPath{
        let mouthWidth = faceRadius / Scaling.FaceRadiusToMouthWidthRatio
        let mouthHeight = faceRadius / Scaling.FaceRadiusToMouthHeightRatio
        let mouthVerticalOffset = faceRadius / Scaling.FaceRadiusToMouthOffsetRatio

        let smileheight = CGFloat(max(min(fractionOfmaxSmile,1), -1)) * mouthHeight

        let start = CGPoint(x: faceCenter.x - mouthWidth/2, y: faceCenter.y + mouthVerticalOffset)

        let end = CGPoint(x:start.x + mouthWidth, y:start.y)
        let cp1 = CGPoint(x:start.x + mouthWidth/3, y:start.y + smileheight)
        let cp2 = CGPoint(x:end.x - mouthWidth/3, y: cp1.y)

        let path = UIBezierPath()
        path.moveToPoint(start)
        path.addCurveToPoint(end, controlPoint1: cp1, controlPoint2: cp2)
        path.lineWidth = lineWidth
        return path
    }

}
时间: 2024-11-06 07:09:48

手势简单应用的相关文章

Android 滑动手势简单使用方法

用法:首先让指定的Activity实现Android.view.OnGestureListener,然后在你需要调用GestureDetector的View上,添加onTouchListener,之后setLongClickable(true)即可. 如: customView.setOnTouchListner(xxxListener); customView.setLongClickable(true); 之后就可以在onFling方法中设置你想要的手势. onFling方法参数解释: on

IOS开发-手势简单使用及手势不响应处理办法

1.点击 2.长按 3.拖拽 4.轻扫.捏合.旋转 5.使用手势需要注意的地方 1.注意处理轻扫和拖拽的冲突 //那个时间短的话 就让那个先执行 //处理 拖拽和轻扫 两个手势的冲突 //需要轻扫手势执行完毕后 再去执行拖拽 先执行轻扫后 再执行拖动 处理方法: [panges(拖拽对象) requireGestureRecognizerToFail:swiges(轻扫对象)]; 2.程序出现手势不响应处理方法 //    手势如果不响应 //    1.看是否添加到了imageView上 如果

2016年最牛逼的分类Android项目源码免费一次性打包下载!

之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年开始不断整理源码区和其他网站上的安卓例子源码,目前总共有810套左右,根据实现的功能被我分成了100多个类,总共接近2.5G,还在不断更新.初学者可以快速方便的找到自己想要的例子,大神也可以看一下别人的方法实现.虽然的例子都是我一个人辛辛苦苦花了很多时间和精力整理的,但是既然这些例子是来自于社区那就让他们免费回归社区吧,(是的!特么的不要一分钱!最看不起那些挂羊头卖狗的)你可以在本帖里面按Ctrl+F查找你需要的关键字,

android源码大放送(实战开发必备),免费安卓demo源码,例子大全文件详细列表

免费安卓demo源码,例子大全文件详细列表 本列表源码永久免费下载地址:http://www.jiandaima.com/blog/android-demo 卷 yunpan 的文件夹 PATH 列表 卷序列号为 0000-73EC E:. │ jiandaima.com文件列表生成.bat │ 例子大全说明.txt │ 本例子永久更新地址~.url │ 目录列表2016.03.10更新.txt │ ├─前台界面 │ ├─3D标签云卡片热门 │ │ Android TagCloudView云标签

转--2014年最新810多套android源码2.46GB免费一次性打包下载

转载自:http://www.eoeandroid.com/thread-497046-1-1.html 感谢该博客主人无私奉献~~ 下面的源码是从今年3月份开始不断整理源码区和其他网站上的安卓例子源码,目前总共有810套左右,根据实现的功能被博主分成了100多个类,总共接近2.5G,还在不断更新.初学者可以快速方便的找到自己想要的例子,大神也可以看一下别人的方法实现.虽然的例子都是博主一个人辛辛苦苦花了很多时间和精力整理的,但是既然这些例子是来自于社区那就让他们免费回归社区吧,(是的!特么的不

【iOS效果集】实现QQ消除小红点(一键退朝)效果

QQ上黏黏的小红点很好玩有木有,于是自己也想实现一番,看到iOS实现的人比较少,Android的比较多,于是这个就用iOS来实现哈~ 效果图: 调试图: 其实从实现来讲,我是先实现第二张图的效果的. 实现思路 1.了解原理,以及如何绘制"黏黏"形状(即绘制两圆加两条贝塞尔曲线). 2.新建UIView(AZMetaBallCanvas),作为单独画布用来绘制"黏黏"形状,用程序实现算法,并绘制出来. 3.给画布(AZMetaBallCanvas)添加attach:(

ym——android源代码大放送(实战开发必备)

转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! 目录 PATH 列表 卷序列号为 000A-8F50 E:. │  javaapk.com文件列表生成工具.bat │  使用说明.txt │  免费下载很多其它源代码.url │  文件夹列表.txt │ ├─android web应用 │      jqmDemo_static.zip │      jqmMobileDemo-master.zip │      jqmMobil

swipe Rotation Pan

1. swipe手势 简单代码: _mySwipeGR = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipes:)]; //设定轻扫手势方向: //只检测符合设定的这个方向的手势 _mySwipeGR.direction = UISwipeGestureRecognizerDirectionLeft; //设定轻扫手势手指数: //必须需要的手指数 _mySwipeGR.number

iOS开发-UIScrollView原理

转载:http://www.cnblogs.com/xiaofeixiang/p/5144256.html UIScrollView 在开发中是不可避免,关于UIScrollView都有自己一定的理解.滚动视图有两个需要理解的属性,frame和bounds,frame是定义了视 图在窗口的大小和位置,bounds表示视图在其自身坐标系中的位置和大小,frame影响视图在窗口位置,bounds会影响子视图的位置. 先来看一张图片: 我们用一个父View将整个窗口铺满,然后添加子视图: UIView