在这一话中我们将应用上一话学到的知识来为Demo添加手势识别,首先添加一个缩放的功能,其次添加一个拖动功能,使得小人的表情可以随着我们的手指改变。

首先来添加一个缩放手势的识别器,我们来到FaceView的代码中,之前定义了一个属性scal用来表示表情的缩放比例,现在我需要一个非私有的方法来修改这个值:

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

别忘了最后把gesture的scale重置为1,因为我希望我每次缩放都基于上一次缩放的比例。

然后回到我们的控制器(HappinessViewController)代码中,修改如下:

 @IBOutlet weak var faceView: FaceView!{
didSet{
faceView.dataSource = self
faceView.addGestureRecognizer(UIPinchGestureRecognizer(target: faceView, action: "scale:"))
}
}

可以看到我们在之前的代码中只是增加了一行而已。现在来运行一下试试,有个问题是我如何在模拟器上模拟两个手指的操作,我只有一个鼠标。

答案是按住option键,这时你模拟了两个手指的动作,这两个手指与中心相对称。现在我可以进行缩放了。

放大:

缩小:

现在我们继续,你可以看到添加一个手势识别是非常简单的。现在来添加一个拖动的手势识别器,当我向上拖动时我希望小人变得开心,向下的话变得难过。我们在控制器中继续添加代码,依旧在faceView的属性观察器中:

faceView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: "changeHappiness:"))

这一次有些区别,因为target选用了控制器本身,这是因为我们要修改的是模型的值,所以target应该选用控制器。然后来添加changeHappiness方法的代码:

当然这样做是为了演示如何跟上一个识别器做出区别,其实我们不需要这行代码,我们可以直接在storyboard中添加识别器!那么现在删掉这行代码,来到storyboard中,找到识别器,就是这些个蓝色的。

然后拖动一个Pan识别器到我们的视图中,你会发现拖拽过来的识别器一下子就消失了,它去哪里了呢?

有两个地方可以找到你刚刚放置的那个识别器,一个是在大纲视图中:

另一个就是在视图的顶部:

现在你所需要做的就是让这个识别器杯碟控制器所处理,跟其他控件的用法一样,采用联合视图然后拖拽到控制器代码中:

那么我们在这个方法中要做些什么呢?我们想要把手指上下滑动的坐标变换解释成小人的嘴部弧线,这一次控制器又一次充当了解释的角色,为模型解释现在视图正发生些什么。这与我们之前讲的为视图去解释模型对应起来了,这是一个相互的过程,而控制器就是那个中间角色。

方法代码:

@IBAction func changeHappiness(gesture: UIPanGestureRecognizer) {
switch gesture.state{
case .Ended: fallthrough
case .Changed:
let translation = gesture.translationInView(faceView)
let happinessChanged = -Int(translation.y / Constants.HappinessGestureScale)
if happinessChanged != 0 {
happiness += happinessChanged
gesture.setTranslation(CGPointZero, inView: faceView)
}
default:break
}
}

我们不希望一点微笑的移动对小人的表情有太大影响,所以我们对手势拖动的数值距离除了一个值,这个值在结构体中定义,所以我们可以根据自己的需要调整它:

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

现在运行试试看吧,不但可以拖动,缩放的手势依旧可以被识别,系统可以很容易辨别出不同的手势。

【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记19 为Demo添加手势的更多相关文章

  1. 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记30 ScrollView Demo实战

    在上一话中我们创建了一个通过URL读取图片的Demo,这个Demo是不能拖动和缩放的.如今给它添加选项让它能够手动切换URL,并把图片加入到ScrollView中. 向Storyboard中拖入一个s ...

  2. 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记1 IOS8概述

    首先感谢网易公开课和SwiftV课堂的朋友们辛苦翻译,这个系列是我学习斯坦福IOS8公开课的个人心得体会和笔记,希望能给大家带来启发. 首先我们要知道IOS系统中的结构情况,从贴近硬件的底层到贴近用户 ...

  3. 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记2 Xcode、Auto Layout及MVC

    原文链接不知道在哪, 接着上一话来讲,上一话中讲到了MVC,那么MVC在IOS8开发中是如何应用的呢?Paul Hegarty老师给我们展示了一个计算器的Demo,首先新建一个工程,老师把AppDel ...

  4. 斯坦福iOS7公开课7-9笔记及演示Demo

    这一部分主要介绍了iOS的绘图.手势.协议.block.力学特效动画(包括重力.碰撞.吸附等)以及自动布局的内容. 1.绘图.手势 (1)调用一个自定义的UIView时,可以使用awakeFromNi ...

  5. 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记3 Xcode、Auto Layout及MVC

    继续上一话中的计算器Demo.上一话讲到类必须被初始化.类中的属性也必须被初始化,所以你不能仅仅声明而不给它一个处置,那么问题来了,我们从storyboard中拖拽的@IBOutlet为什么仅仅有声明 ...

  6. 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记38 Unwind Segue反向过渡

    之前我们接触过了segue,这是IOS中最主要的传递方式,今天来解说一下怎样进行反向的segue. 反向过渡的使用前提是发出过渡的MVC必须是由目标MVC直接或者间接正向过渡来的.反向过渡是唯一不会创 ...

  7. 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记35 UITextField文本框

    本话来介绍UIKit框架中的组件UITextField. UItextField(文本框)和Label看起来看像,可是文本框是能够编辑的.在UI中使用文本框要注意.由于在模拟器上面输入文字是能够使用电 ...

  8. 斯坦福iOS7公开课11笔记及演示Demo&访问HTTPS链接下载数据

    这一节主要介绍UITableView以及iPad,Demo为从Flicker下载图片并显示,但是实际过程中发现需要FQ并使用HTTPS连接,所以这次用了两个Demo,一个是课程中的Demo,另一个是简 ...

  9. 斯坦福iOS7公开课10笔记及演示Demo

    这一节主要介绍了多线程中的串行队列以及滚动视图UIScrollView. 1 .多线程 这一节只是简单介绍了多线程的串行队列,即把任务加入线程队列后按顺序逐步执行. (1)目前iOS多线程提供的方法主 ...

随机推荐

  1. RS485连接CAN——应急用法【worldsing笔记】【待完善】

    阅读前提:假设读者对CAN总线和485总线有一定了解. RX485连接CAN用法提出背景: 在一般情况下只能是CAN对CAN 485对485, 但是在调试过程中难免对出现设备没有CAN接口,或是没有4 ...

  2. 认识CoreData-高级用法

    来源:伯乐在线专栏作者 - 刘小壮 链接:http://ios.jobbole.com/87293/ 点击 → 了解如何加入专栏作者 认识CoreData-初识CoreData 认识CoreData- ...

  3. C# Winform 支持Hex与ASCII输入和切换的文本框

    最近一直在做一个支持串口,TCP,UDP通讯调试的一体化工具(也就是C#串口调试工具 v2.0的第三版),其中涉及到16进制数据和ASCII码的输入,所以继承了TextBox的基础上,写了这个支持He ...

  4. Foxmail

    我们在“POP3/SMTP服务”前面打钩,这样我们的QQ邮箱设置已经完成了,我们就可以在foxmail客户端上QQ邮箱了 QQ邮箱的POP3与SMTP服务器是什么? QQ邮箱 POP3 和 SMTP ...

  5. 字母A-Z写法

    #大写的a-z,ASCII编码 65..90|%{[char]$_}     #小写的A-Z  97..122|%{[char]$_}    方法二: ([char[]](97..122) -as [ ...

  6. 【09】绝不在构造和析构过程中调用virtual方法

    1.绝不在构造和析构过程中调用virtual方法,为啥? 原因很简单,对于前者,这种情况下,子类专有成分还没有构造,对于后者,子类专有成分已经销毁,因此调用的并不是子类重写的方法,这不是程序员所期望的 ...

  7. iOS开发——开发技巧&Git常用命令

    Git常用命令 初始化git init        加—bare实现远程仓库 配置git config user.name iCocos 配置全局git config —global user.na ...

  8. Android(java)学习笔记121:android.intent.action.MAIN 与 android.intent.category.LAUNCHER 理解

    先看看网路上的说法: android.intent.action.MAIN决定应用程序最先启动的 Activity android.intent.category.LAUNCHER决定应用程序是否显示 ...

  9. 运用surfaceView与MediaPlayer实现播放视频的功能

    该程序运用了surfaceView与MediaPlayer结合,实现播放视频,surfaceView详情请见 SurfaceView的使用 使用了第三方包Volly里面的方法StringQueue下载 ...

  10. iOS 对网络视频采集视频截图

    在播放网络视频是  经常可以看到播放按钮下面是该制品的某个截图 : 一般情况下  后台服务器是可以把视频截图一起返回给你 你直接拿到图片显示就可以了 但是当后台没有提供时  我们也可以根据视频地址 自 ...