Men的博客

欢迎光临!

0%

● 加速计的作用
● 用于检测设备的运动(比如摇晃)
● 加速计的经典应用场景 ● 摇一摇
● 计步器
加速计的原理
● 检测设备在X、Y、Z轴上的加速度 (哪个方向有力的作用,哪个方向运动了) ● 根据加速度数值,就可以判断出在各个方向上的作用力度
加速计程序的开发
● 加速计程序的开发
● 在iOS4以前:使用UIAccelerometer,用法非常简单(到了iOS5就已经过
期)
● 从iOS4开始:CoreMotion.framework
● 虽然UIAccelerometer已经过期,但由于其用法极其简单,很多程序里面都 还有残留
UIAccelerometer的使用步骤
● 获得单例对象
UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
● 设置代理 accelerometer.delegate = self;
● 设置采样间隔
accelerometer.updateInterval = 1.0/30.0; // 1秒钟采样30次
● 实现代理方法

  • (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:
    (UIAcceleration *)acceleration
    // acceleration中的x、y、z三个属性分别代表每个轴上的加速度
    Core Motion
    ● 在iOS4之前,加速度计由UIAccelerometer类来负责采集数据
    ● 随着iPhone4的推出
    ● 加速度计全面升级,并引入了陀螺仪
    ● 与Motion(运动)相关的编程成为重头戏
    ● 苹果特地在iOS4中增加了专门处理Motion的框架-CoreMotion.framework
    ● Core Motion不仅能够提供实时的加速度值和旋转速度值,更重要的是,苹果 在其中集成了很多牛逼的算法
    Core Motion获取数据的两种方式
    ● push
    ● 实时采集所有数据(采集频率高)
    ● pull
    ● 在有需要的时候,再主动去采集数据
    Core Motion的使用步骤(push)
    ● 创建运动管理者对象
    CMMotionManager *mgr = [[CMMotionManager alloc] init];
    ● 判断加速计是否可用(最好判断)
    if (mgr.isAccelerometerAvailable) {
    // 加速计可用 }
    ● 设置采样间隔
    mgr.accelerometerUpdateInterval = 1.0/30.0; // 1秒钟采样30次
    ● 开始采样(采样到数据就会调用handler,handler会在queue中执行)
  • (void)startAccelerometerUpdatesToQueue:(NSOperationQueue *)queue
    withHandler:(CMAccelerometerHandler)handler;
    Core Motion的使用步骤(pull)
    ● 创建运动管理者对象
    CMMotionManager *mgr = [[CMMotionManager alloc] init];
    ● 判断加速计是否可用(最好判断)
    if (mgr.isAccelerometerAvailable) { // 加速计可用 }
    ● 开始采样
  • (void)startAccelerometerUpdates;
    ● 在需要的时候采集加速度数据
    CMAcceleration acc = mgr.accelerometerData.acceleration; NSLog(@”%f, %f, %f”, acc.x, acc.y, acc.z);
    Core Motion框架结构示意图
    摇一摇
    ● 监控摇一摇的方法
    ● 方法1:通过分析加速计数据来判断是否进行了摇一摇操作(比较复杂) ● 方法2:iOS自带的Shake监控API(非常简单)
    ● 判断摇一摇的步骤:实现3个摇一摇监听方法
    ● - (void)motionBegan:(UIEventSubtype)motion withEvent:
    (UIEvent )event /* 检测到摇动 /
    ● - (void)motionCancelled:(UIEventSubtype)motion
    withEvent:(UIEvent )event /
    摇动取消(被中断) /
    ● - (void)motionEnded:(UIEventSubtype)motion withEvent:
    (UIEvent )event /
    摇动结束 */
    更多的设备信息
    ● 如果想获得更多的设备信息,比如
    ● 设备型号、CPU情况、内存使用情况、硬盘使用情况
    ● 是否越狱、装了哪些传感器、当前运行的进程
    ● … …
    ● 有2种方法获取更多的设备信息
    ● 导入底层的C语言库,通过底层的C语言函数获取(较复杂,需要很多时间去
    研究)
    ● 使用第三方库(用OC封装了底层的C函数)
    https://github.com/Shmoopi/iOS-System-Services
    https://github.com/erica/uidevice-extension

iPhone5中内置的传感器有
● 运动传感器\加速度传感器\加速计(Motion/Accelerometer Sensor)
● 环境光传感器(Ambient Light Sensor)
● 距离传感器(Proximity Sensor)
● 磁力计传感器(Magnetometer Sensor)
● 内部温度传感器(Internal Temperature Sensor)
● 湿度传感器(Moisture Sensor)
● 陀螺仪(Gyroscope)
● … …
环境光传感器(Ambient Light Sensor)
● 是iOS、Mac设备中最为古老的传感器成员
● 它能够让你在使用 Mac、iPhone、iPad时,眼睛更为舒适
● 从一个明亮的室外走入相对黑暗的室内后,iOS设备会自动调低亮度,让屏幕显得不再那 么光亮刺眼
● 当你使用iPhone拍照时,闪光灯会在一定条件下自动开启
● 几乎所有的Mac 都带有背光键盘,当周围光线弱到一定条件时,会自动开启键盘背光
距离传感器(Proximity Sensor)
● 用于检测是否有其他物体靠近设备屏幕
● 当你打电话或接电话时将电话屏幕贴近耳边,iPhone会自动关闭屏幕 ,好处是
● 节省电量
● 防止耳朵或面部不小心触摸屏幕而引发一些不想要的意外操作
● 题外话:利用距离传感器,能找出很多电视剧的穿帮镜头
磁力计传感器(Magnetometer Sensor)
● 可以感应地球磁场, 获得方向信息, 使位置服务数据更精准 ● 可以用于电子罗盘和导航应用
● iPad的Smart Cover盒盖睡眠操作就是基于磁力计传感器
内部温度传感器(Internal Temperature Sensor)
● 从 iPad一代开始,iOS设备都加入了一个内部温度传感器,用于检测内部组件 温度,当温度超过系统设定的阈值时,会出现以下提示
● 内部温度传感器,对于提升iOS设备自身安全性与稳定性有很大的帮助
湿度传感器(Moisture Sensor)
● 湿度传感器跟其他基于微电子的传感器不同,是一个简单的物理传感器 ● 简单来说,湿度传感器就是一张遇水变红的试纸
● Apple的维修人员就是通过检测试纸是否变红,来判断设备是否进水 (设备进水不在保修范围之内)
陀螺仪(Gyroscope)
● 陀螺仪是随着iPhone4的上市首次出现在iOS设备上的传感器 ● 陀螺仪可以用于检测设备的持握方式
● 陀螺仪的原理是检测设备在X、Y、Z轴上所旋转的角速度
● 陀螺仪在赛车类游戏中有重大作用: ● 模拟汽车驾驶时方向盘旋转的动作
● 使得这类游戏的操控体验更为真实
运动传感器\加速度传感器\加速计(Motion/Accelerometer Sensor)
● 最早出现在iOS设备上的传感器之一
● 加速计用于检测设备在X、Y、Z轴上的加速度 (哪个方向有力的作用)
● 加速计可以用于检测设备的摇晃,经典应用场景 ● 摇一摇
● 计步器

传感器总结

传感器类型
作用
环境光传感器
感应周边环境光线的强弱(自动调节屏幕亮度)
距离传感器
感应是否有其他物体靠近设备屏幕(打电话自动锁屏)
磁力计传感器
感应周边的磁场(合盖锁屏)
内部温度传感器
感应设备内部的温度(提醒用户降温,防止损伤设备)
湿度传感器
感应设备是否进水(方便维修人员)
陀螺仪
感应设备的持握方式(赛车类游戏)
加速计
感应设备的运动(摇一摇、计步器)

距离传感器的使用

// 开启距离感应功能
[UIDevice currentDevice].proximityMonitoringEnabled = YES; // 监听距离感应的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(proximityChange:) name:UIDeviceProximityStateDidChangeNotification object:nil];

  • (void)proximityChange:(NSNotificationCenter *)notification { if ([UIDevice currentDevice].proximityState == YES) { NSLog(@”某个物体靠近了设备屏幕”); // 屏幕会自动锁住
    } else {
    NSLog(@”某个物体远离了设备屏幕”); // 屏幕会自动解锁
    } }

游戏开发相关:

http://www.gameres.com/ 想学游戏的这个网站绝对不能错过,个人感觉挺不错的
http://xyq.baike.163.com/ziliao/ SLG 游戏系统策划
http://www.gamedev.net/page/index.html 国外
http://ns.codingnow.com/ 网易梦幻西游后端主程序 大神

安全相关:
http://bbs.pediy.com/ 看雪学院 国内重量级

iOS相关:

http://blog.devtang.com/ 网易iOS

http://beyondvincent.com/blog/archives/
http://github.ibireme.com/github/list/ios/ 收集git 上各种优秀项目

Swift学习:
https://github.com/CocoaChina-editors/Welcome-to-Swift
https://github.com/numbbbbb/the-swift-programming-language-in-chinese

热门IT社区
www.csdn.net
www.cnblogs.com
www.51cto.com
http://www.oschina.net/

http://tool.oschina.net/apidocs/#J 在线API 各种技术文档

http://www.juming.com/Csdn/#jieguo 免CSDN下载器

http://www.cnpaf.net/class/rfcall/ 网络协议详解大全

如果使用autolayout来约束控件, 那fraem就失效了, 官方也不建议我们再设置frame了

宽度: 100
高度: 100
水平居中: X
垂直居中: Y
注意: 如果利用autolayout约束一个控件, 和我们以前使用frame约束控件一样, 必须设置宽度/高度/X/Y , 如果缺少某一个约束就会报错, 报错有可能会引发一些未知的bug

如果有红色警告:
代表缺少约束
如果有黄色警告:
代表控件当前的位置大小和约束的位置大小不一样

距离顶部: 20 相当于设置了Y
距离左边:20 相当于设置了X
距离右边:20 相当于设置了宽度
距离底部:20 相当于设置了高度

注意:
在使用Autolayout时,最好给每个控件起一个名称, 方便阅读

  1. 应用场景

1) 使用第三方用户登录,需要用户授权,还需要”返回到调用的程序,同时返回授权的用户名”

2) 应用程序推广,网易彩票,设置-推荐应用-有很多应用程序图标
-如果本机已经安装过,会直接跳转到另外一个应用程序
-软件的广告,推广结果,后续会有一些列的金钱上的结算

  1. 支付宝,第三方支付,淘宝,电话费充值。。。
  1. 要打开本机上的其他应用程序,需要设置schemes,自定义的协议头,可以打开其他的应用程序

跳转的代码如下:

  • (IBAction)openWangyi:(id)sender
    {
    // 跳转到其他应用程序
    // schemes: 网易的scheme wangyi
    NSURL *url = [NSURL URLWithString:@”wangyi://view?newsid=201410130001”];

// 判断本机是否安装了目标程序
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
} else {
NSLog(@”没有安装,可以再给定下载地址,前往”);
}
}

  1. 新浪微博的授权界面说明:

1> 在新浪微博中,本身不能直接跳转到该界面
2> 用其他应用程序打开时,如果scheme时weibo://oaauth,直接进入此界面
3> 如果直接点击,返回,返回调用放应用程序
4> 如果点击表格行中的用户名,直接返回用户信息给调用应用程序

  1. 如果要返回调用的应用程序,需要知道调用我们的应用程序的scheme

/** 只要是由其他应用程序打开的,就会调用此方法 /
/*
URL 就是其他应用程序,打开当前程序使用的URL */

  • (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url

/**
openURL 是打开当前应用程序的url
sourceApplication 是当开当前应用程序的源程序的BundleId

提示:一旦重写了新方法,旧方法就不再被执行
但是:很多第三方框架,都建议两个方法全都写
*/

  • (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation


CLLocationManager 定位管理者
CLLocation 代表位置(经度/纬度/高度/速度/路线等)
CLHeading 代表移动方向
CLRegion 代表一个区域

CLCircularRegion 圆形区域
CLBeaconRegion 蓝牙信号区域

返回定位服务是否可用
[CLLocationManager locationServicesEnabled];
返回延迟定位更新是否可用
[CLLocationManager deferredLocationUpdatesAvailable];
返回重大位置改变监听是否可用
[CLLocationManager significantLocationChangeMonitoringAvailable];
返回是否支持磁力计算方向
[CLLocationManager headingAvailable];
返回蓝牙信号范围服务是否可用
[CLLocationManager isRangingAvailable];


设置是否可以暂停定位来节省电池电量, YES不需要定位数据时自动暂停定位
// mgr.pausesLocationUpdatesAutomatically


每隔多少米定位一次, 只有水平方向超过该值时才会重新定位
// mgr.distanceFilter = 100;


定位精确度
// mgr.desiredAccuracy;
kCLDistanceFilterNone;
kCLLocationAccuracyBestForNavigation 导航级最佳精准
kCLLocationAccuracyBest; 最佳精准
kCLLocationAccuracyNearestTenMeters; 10米误差
kCLLocationAccuracyHundredMeters; 百米胡茬
kCLLocationAccuracyKilometer; 千米误差
kCLLocationAccuracyThreeKilometers; 3千米误差


定位数据的用途
// mgr.activityType;
CLActivityTypeOther 作为普通用途
CLActivityTypeAutomotiveNavigation 作为车辆导航
CLActivityTypeFitness 作为不行
CLActivityTypeOtherNavigation 作为其它导航


// CLLocation
location.coordinate; 坐标, 包含经纬度
location.altitude; 设备海拔高度 单位是米
location.course; 设置前进方向 0表示北 90东 180南 270西
location.horizontalAccuracy; 水平精准度
location.verticalAccuracy; 垂直精准度
location.timestamp; 定位信息返回的时间
location.speed; 设备移动速度 单位是米/秒, 适用于行车速度而不太适用于不行
/*
可以设置模拟器模拟速度
bicycle ride 骑车移动
run 跑动
freeway drive 高速公路驾车
*/


// CLAuthorizationStatus
用户从未选择过权限
kCLAuthorizationStatusNotDetermined
无法使用定位服务,该状态用户无法改变
kCLAuthorizationStatusRestricted
用户拒绝该应用使用定位服务,或是定位服务总开关处于关闭状态
kCLAuthorizationStatusDenied
已经授权(废弃)
kCLAuthorizationStatusAuthorized
用户允许该程序无论何时都可以使用地理信息
kCLAuthorizationStatusAuthorizedAlways
用户同意程序在可见时使用地理位置
kCLAuthorizationStatusAuthorizedWhenInUse


// 计算两个位置之间的距离, 单位是米
[newLocation distanceFromLocation:self.prevLocation];


获取方向信息不会提示用户(不需要授权), 因为不会泄露隐私
// [self.mgr startUpdatingHeading];

magneticHeading 设备与磁北的相对角度
trueHeading 设置与真北的相对角度, 必须和定位一起使用, iOS需要设置的位置来计算真北
真北始终指向地理北极点
磁北对应随着时间变化的地球磁场北极
@interface ViewController ()
{
//创建对象
CLLocationManager *_manager;
}

//获取当前经度
_manager =[[CLLocationManager alloc]init];
//设置代理
_manager.delegate=self;

开始定位
[self startLocation];
#pragma mark - 开始定位
-(void)startLocation
{
//判断定位服务是否可用
if (![CLLocationManager locationServicesEnabled]) {
NSLog(@”定位服务不可用”);

}

//设置精确度
_manager.desiredAccuracy=kCLLocationAccuracyBestForNavigation;
//距离变化敏感程度
_manager.distanceFilter=1000;
//开始定位
[_manager startUpdatingLocation];
}
#pragma mark - 协议提供的代理方法,当位置更新的时候执行
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
//地址:经纬度

//获取地址对象(包含经纬度)
CLLocation *location=manager.location;
//获取当前经纬度
CLLocationCoordinate2D coordinate=location.coordinate;
//输出经纬度
NSLog(@”long=%f lan=%f”,coordinate.longitude,coordinate.latitude);

}

方向服务
// [self testHeading];
#pragma mark - 方向服务
-(void)testHeading
{
if (![CLLocationManager headingAvailable]) {
NSLog(@”方向服务不可用”);
return;
}
[_manager startUpdatingHeading];
}
#pragma mark - 代理方法,当方向更新的时候开始执行
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{

NSLog(@”磁极方向= %f”,newHeading.magneticHeading);
NSLog(@”地理方向 = %f”,newHeading.trueHeading);
}

地址编码和地址反编码
[self testGeoCoder];
#pragma mark - 地址编码和地址反编码
-(void)testGeoCoder
{
//知道地址,获取经纬度===地址编码
CLGeocoder *geocoCoder=[[CLGeocoder alloc]init];
[geocoCoder geocodeAddressString:@”兴美生活广场” completionHandler:^(NSArray *placemarks, NSError *error) {
//返回placemarks
for (CLPlacemark *mark in placemarks)
{
NSLog(@”mark=%@”,mark );
}
}];
//地址反编码,知道经纬度,获取地址,
CLLocation *location=[[CLLocation alloc]initWithLatitude:40.03708400 longitude:116.37059500];

CLGeocoder *reverseGeocoCoder=[[CLGeocoder alloc]init];
[reverseGeocoCoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
for (CLPlacemark *mark in placemarks)
{
NSLog(@”地址反编码=%@”,mark );

}
}];

}

1> 事件处理简介

  • PPT简介
  • 3大事件:主要了解触摸事件。
  • 什么是响应者对象
  • 为什么继承UIResponder就能处理事件
  • 想处理触摸事件,应该怎么办

2> 01-view拖拽演练

  • 为什么要自定义view:系统自带不能处理事件
  • 演示触摸事件方法,触摸的完整过程。
  • 介绍参数(NSSet,UITouch,UIEvent)
  • 重点UITouch,

1.触摸事件方法中的UITouch都是同一个对象,因为一根手指对应一个UITouch.当手指移动或者抬起,并不会产生一个新的UITouch对象给你,而是改变UITouch里面的属性,
1.默认三个方法里面只能获取到一个手指,为什么。UIView不支持多点触控
2.怎么才能有两个手指,两个手指同时按,并且视图支持多点触控
3.UITouch的tapCount有什么用?可以判断用户当前是双击还是单击
4.UITouch的phase有什么用? 根据这个属性,判断当前需要调用哪个处理事件方法,begin,move,end
程序思路:

  • 在TouchMove里面做事情-为什么?因为用户手指在视图上移动的时候才需要移动视图。
  • 获取用户当前的位置,获取用户之前的位置,就知道用户从哪移动到哪,这个位置也是视图移动的位置
  • 当前视图的位置 = 上一次视图的位置 + 手指的偏移量

3> 02-事件传递

  • PPT简介
  • 事件,加入到一个由谁管理的事件队列中?UIApplication
  • 为什么用队列,不用栈。队列先进先出,意味着先产生的事件,先处理。
  • 代码验证事件谁处理
  • PPT上这么多view,验证哪个view处理事件。这么多view,都需要监重写一个方法,搞个父类。
  • 一个view能处理事件,意味着事件传递给他了,那怎么传递? 事件是由父控件传递给子控件。
  • 父控件不处理事件,子控件也不能。蓝色不接收事件,黄色也不会接收事件? 为什么,因为事件是从父控件传递给子控件的。父控件都没有事件,怎么传给子控件。
  • 代码验证view不能处理事件
  • 一个view怎么不能处理事件。userInteractionEnabled = NO,hidden = YES,alpha <= 0.01
  • 代码验证UIImageView不允许交互
  • UIImageView默认不允许用户交互,因此默认它上面的子控件不能接收事件。
  • 怎么找到最合适的View?通过一个递归。
  • 第一个接收事件的控件是谁?窗口
  • 当事件传递给窗口的时候,就会让窗口去找最合适的view,1> 判断自己能不能接收事件 2> 点在不在窗口上 3> 去找比自己更合适的view,从后往前遍历子控件,拿到子控件后,把事件传递给这个子控件 4> 子控件拿到事件之后,又会做同样的判断,一直递归去找,直到找到最合适的view.
  • 事件传递的目的何在?找到最合适的view,把事件交给他。

4> 03-hitText方法和pointInside方法(复制:02-事件传递代码)

  • (了解hitText)学习一个方法必须了解:什么时候调用和这个方法有什么用
  1. hitText什么时候调用:当一个事件传递给一个控件的时候,控件就会调用这个方法
  2. hitText作用: 寻找到最合适的view。
  • (回顾下事件传递),UIApplication -> UIWindow
  • UIWindow去寻找最合适的view? [UIWindow hitTest:withEvent:]里面做了什么事情?
    1> 判断窗口能不能处理事件? 如果不能,意味着窗口不是最合适的view,而且也不会去寻找比自己更合适的view,直接返回nil,通知UIApplication,没有最合适的view。
    2> 判断点在不在窗口
    3> 遍历自己的子控件,寻找有没有比自己更合适的view
    4> 如果子控件不接收事件,意味着子控件没有找到最合适的view,然后返回nil,告诉窗口没有找到更合适的view,窗口就知道没有比自己更合适的view,就自己处理事件。
  • 验证下hitTest方法返回nil,里面的子控件能处理事件吗? 重写根控制器view的hitTest:withEvent:方法,
  • 验证这个方法是否真能找到最合适的view?
  • 如果点击屏幕任何一个地方,都是白色的view,怎么做。直接返回白色的view,就不会继续去找白色view的子控件了。
  • 介绍pointInside方法
  • pointInside作用:判断一个点在不在一个控件上
  • point参数:方法调用者坐标系上的点,PPT画图分析原理。
  • 这节课的重点:学习完了pointInside,就能实现下hitTest方法底层是怎么做的了。

5> 04-hitText练习

  • 分析思路:如果一个点,同时在黄色view和按钮上,由按钮处理事件,怎么做?
  • 分析事件传递: 当黄色按钮要处理事件,首先事件得传递到他身上
  • 重写hitTest方法:事件传递到某个控件,调用什么方法?hitTest
  • 返回nil什么意思?如果直接返回nil,意味着黄色的view,没有找到最合适的view,他的父控件,就会遍历下一个控件,也就是按钮,询问按钮是不是最合适的view.
  • 判断点在不在按钮上,在就交给他处理。
  • pointInside实现。

5> 响应者链条(复制:02-事件传递代码)

  • PPT简介
  • touch默认做法:自己不处理事件,交给上一个响应者处理touch事件。
  • 响应者链条,点击绿色的view,如果不处理事件,就会往上传递。
  • 验证touch的默认做法 先恢复所有view的默认做法
  • 监听黄色点击,蓝色点击。
  • 黄色调用默认做法,事件传递给谁处理?蓝色
  • 得出结论:1> touch的默认做法:自己不处理,交给上一个响应者。 2> 上一个响应者默认是父控件
  • 两个view怎么同时处理事件?一个view处理方法,在调用父类默认的做法
  • 把事件传递给白色的view,怎么做?
  • 总结下事件传递的完整过程.
  • 把事件传递给控制器,测试白色view的上一个响应者是否是控制器。
  • 回顾响应者链条

6> 抽屉效果
添加子视图

  • 简单的滑动效果
  • 监听控制器处理事件方法
  • 获取x轴偏移量
  • 改变主视图的frame
  • 利用KVO做视图切换
    往左移动,显示右边,隐藏左边
    往右移动,显示左边,隐藏右边
  • 复杂的滑动效果,PPT讲解(根据手指每移动一点,x轴的偏移量算出当前视图的frame)
    假设x移到320时,y移动到60,算出没移动一点x,移动多少y
    offsetY = offsetX * 60 / 320 手指每移动一点,x轴偏移量多少,y偏移多少
    为了好看,x移动到320,距离上下的高度需要保持一致,而且有一定的比例去缩放他的尺寸。
    怎么根据之前的frame,算出当前的frame,touchMove只能拿到之前的frame.
    当前的高度 = 之前的高度 * 这个比例
    缩放比例:当前的高度/之前的高度 (screenH - 2 * offsetY) / screenH
    当前的宽度也一样求。
    y值,计算比较特殊,不能直接用之前的y,加上offsetY,往左滑动,主视图应该往下走,但是offsetX是负数,导致主视图会往上走。
    y = (screenH - 当前的高度)* 0.5
    getCurrentFrameWithOffsetX
  • 定位(滑动松开手指的时候,移动到目标点)
    移动到左右目标点,根据偏移量 = 当前目标点的x - 之前视图的x,计算移动到目标点的frame
    还原:当没有移动到目标点,就把主视图还原。
  • 复位(当主视图不在原始的位置,点击屏幕,恢复原来位置)
    判断手指是否移动,移动的时候就自动定位,不需要手动复位。

7> 手势识别
使用UIImageView原因:之前既能看见图片,又能监听点击的只有UIButton,学了手势,我们的UIImageView也可以。

  • tap(代理:左边不能点,右边能点)
  • longPress(allowableMovement:触发之前,最大的移动范围)

    默认调用两次,开始一次,结束一次。

  • swipe:(一个手势只能识别一个方向)
  • 旋转:
    基于上一次旋转
  • 复位:(手势的取值都是相对最原始的位置,我们应该是需要相对上一次,因此每次调用,就复位一下,每次都是从零开始旋转角度)
    缩放:复位
  • 如何同时支持旋转和缩放?默认不支持多个手指,
    Simultaneously:同时
    当使用一个手势的时候会调用代理的Simultaneously方法,询问是否支持多个手势
  • pan
    获取平移的位置:translationInView
    复位:setTranslation:inView: 需要传一个view,因为点的位置跟坐标系有关系,看他是基于哪个坐标系被清空的。

Info.plist

● 建立一个工程后,会在Supporting files文件夹下看到一个“工程名-Info.plist”的文件,该文 件对工程做一些运行期的配置,非常重要,不能删除
● 在旧版本Xcode创建的工程中,这个配置文件的名字就叫“Info.plist”
● 项目中其他Plist文件不能带有“Info”这个字眼,不然会被错认为是传说中非常重要
的“Info.plist”
● 项目中还有一个InfoPlist.strings的文件,跟Info.plist文件的本地化相关
● 常见属性(红色部分是用文本编辑器打开时看到的key)
● Localiztion native development region(CFBundleDevelopmentRegion)-本地化相关
● Bundle display name(CFBundleDisplayName)-程序安装后显示的名称,限制在10-12个字 符,如果超出,将被显示缩写名称
● Icon file(CFBundleIconFile)-app图标名称,一般为Icon.png
● Bundle version(CFBundleVersion)-应用程序的版本号,每次往App Store上发布一个新版
本时,需要增加这个版本号
● Main storyboard file base name(NSMainStoryboardFile)-主storyboard文件的名称
● Bundle identifier(CFBundleIdentifier)-项目的唯一标识,部署到真机时用到

pch文件

● 项目的Supporting files文件夹下面有个“工程名-Prefix.pch”文件,也是一个头文件
● pch头文件的内容能被项目中的其他所有源文件共享和访问
● 一般在pch文件中定义一些全局的宏
● 在pch文件中添加下列预处理指令,然后在项目中使用Log(…)来输出日志信息,就可以 在发布应用的时候,一次性将NSLog语句移除(在调试模式下,才有定义DEBUG)
#ifdef DEBUG
#define Log(…) NSLog(VA_ARGS)
#else
#define Log(…) /* */
#endif

UIApplication

● UIApplication对象是应用程序的象征
● 每一个应用都有自己的UIApplication对象,而且是单例的
● 通过[UIApplication sharedApplication]可以获得这个单例对象
● 一个iOS程序启动后创建的第一个对象就是UIApplication对象
● 利用UIApplication对象,能进行一些应用级别的操作
UIApplication的常用属性
● 设置应用程序图标右上角的红色提醒数字
@property(nonatomic) NSInteger applicationIconBadgeNumber;
● 设置联网指示器的可见性 @property(nonatomic,getter=isNetworkActivityIndicatorVisible)
BOOL networkActivityIndicatorVisible;
iOS7中的状态栏
● 从iOS7开始,系统提供了2种管理状态栏的方式
➢ 通过UIViewController管理(每一个UIViewController都可以拥有自己不同的状
态栏)
➢ 通过UIApplication管理(一个应用程序的状态栏都由它统一管理)
● 在iOS7中,默认情况下,状态栏都是由UIViewController管理 的,UIViewController实现下列方法就可以轻松管理状态栏的可见性和样式
➢ 状态栏的样式

  • (UIStatusBarStyle)preferredStatusBarStyle;
    ➢ 状态栏的可见性
  • (BOOL)prefersStatusBarHidden;
    利用UIApplication来管理状态栏
    ● 如果想利用UIApplication来管理状态栏,首先得修改Info.plist的设置
    ● UIApplication有个功能十分强大的openURL:方法 - (BOOL)openURL:(NSURL*)url;
    ● openURL:方法的部分功能有
    ➢ 打电话
    UIApplication *app = [UIApplication sharedApplication]; [app openURL:[NSURL URLWithString:@”tel://10086”]];
    ➢ 发短信
    [app openURL:[NSURL URLWithString:@”sms://10086”]];
    ➢ 发邮件
    [app openURL:[NSURL URLWithString:@”mailto://12345@qq.com”]];
    ➢ 打开一个网页资源
    [app openURL:[NSURL URLWithString:@”http://ios.itcast.cn"]];
    ➢ 打开其他app程序
    UIApplication和delegate
    ● 所有的移动操作系统都有个致命的缺点:app很容易受到打扰。比如一个来电或者锁屏 会导致app进入后台甚至被终止
    ● 还有很多其它类似的情况会导致app受到干扰,在app受到干扰时,会产生一些系统事 件,这时UIApplication会通知它的delegate对象,让delegate代理来处理这些系统事件
    ● delegate可处理的事件包括:
    ➢ 应用程序的生命周期事件(如程序启动和关闭) ➢ 系统事件(如来电)
    ➢ 内存警告
    ➢……
    UIApplication和delegate
    // app接收到内存警告时调用 UIApplicationDelegate协议
  • (void)applicationDidReceiveMemoryWarning:(UIApplication *)application; // app进入后台时调用(比如按了home键)
  • (void)applicationDidEnterBackground:(UIApplication *)application;
    // app启动完毕时调用
  • (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
    遵守协议,实现相应的方法
    某个对象
    id delegate UIApplication
    UIApplicationDelegate
    ● 每次新建完项目,都有个带有“AppDelegate”字眼的类,它就是UIApplication的代理
    ● HMAppDelegate默认已经遵守了UIApplicationDelegate协议,已经 是UIApplication的代理

    iOS程序的启动过程

程序加载完毕
程序获取焦点
程序进入后台
程序失去焦点
程序从后台回到前 台
内存警告,可能要
终止程序
程序即将退出
打开程序
执行main函数 执行UIApplicationMain函数
初始化UIApplication(创建和设置代 理对象,开启事件循环)
监听系统事件
结束程序
UIApplication代理 application:
didFinishLaunchingWithOptions:
applicationDidBecomeActive:
applicationDidEnterBackground:
applicationWillResignActive:
applicationWillEnter Foreground:
applicationDidReceiveMemory Warning:
applicationWillTerminate:

● main函数中执行了一个UIApplicationMain这个函数
● intUIApplicationMain(intargc,char*argv[],NSString
principalClassName, NSString delegateClassName); ➢ argc、argv:直接传递给UIApplicationMain进行相关处理即可
➢ principalClassName:指定应用程序类名(app的象征),该类必须是UIApplication(或子 类)。如果为nil,则用UIApplication类作为默认值
➢ delegateClassName:指定应用程序的代理类,该类必须遵守UIApplicationDelegate协 议
UIApplicationMain
● UIApplicationMain函数会根据principalClassName创建UIApplication对象,根 据delegateClassName创建一个delegate对象,并将该delegate对象赋值给UIApplication对象 中的delegate属性
● 接着会建立应用程序的Main Runloop(事件循环),进行事件的处理(首先会在程序完毕后调 用delegate对象的application:didFinishLaunchingWithOptions:方法)
● 程序正常退出时UIApplicationMain函数才返回
UIWindow
● UIWindow是一种特殊的UIView,通常在一个app中只会有一个UIWindow
● iOS程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的view,
最后将控制器的view添加到UIWindow上,于是控制器的view就显示在屏幕上了 ● 一个iOS程序之所以能显示到屏幕上,完全是因为它有UIWindow
● 也就说,没有UIWindow,就看不见任何UI界面
UIView
UIWindow
UIViewController
view
UIWindow
● 添加UIView到UIWindow中两种常见方式:
➢ -(void)addSubview:(UIView
)view; 直接将view添加到UIWindow中,但并不会理会view对应的UIViewController
➢ @property(nonatomic,retain)UIViewController
rootViewController; 自动将rootViewController的view添加到UIWindow中,负责管理rootViewController
的生命周期
● 常用方法
➢ -(void)makeKeyWindow; 让当前UIWindow变成keyWindow(主窗口)
➢ -(void)makeKeyAndVisible; 让当前UIWindow变成keyWindow,并显示出来
UIWindow的获得
● [UIApplicationsharedApplication].windows 在本应用中打开的UIWindow列表,这样就可以接触应用中的任何一个UIView对象 (平时输入文字弹出的键盘,就处在一个新的UIWindow中)
● [UIApplicationsharedApplication].keyWindow
用来接收键盘以及非触摸类的消息事件的UIWindow,而且程序中每个时刻只能有一 个UIWindow是keyWindow。如果某个UIWindow内部的文本框不能输入文字,可能是因为这 个UIWindow不是keyWindow
● view.window 获得某个UIView所在的UIWindow

四大对象关系图

UIApplication
delegate
HMAppDelegate
window
UIViewController
view
UIWindow
rootViewController
xib\storyboard\代码

简单介绍

1.什么是UIDynamic
UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架
可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象
如:重力、弹性碰撞等现象
 
2.物理引擎的价值
广泛用于游戏开发,经典成功案例是“愤怒的小鸟”
让开发人员可以在远离物理学公式的情况下,实现炫酷的物理仿真效果
提高了游戏开发效率,产生更多优秀好玩的物理仿真游戏
 
3.知名的2D物理引擎
Box2d
Chipmunk  

使用步骤

要想使用UIDynamic来实现物理仿真效果,大致的步骤如下
(1)创建一个物理仿真器(顺便设置仿真范围)
(2)创建相应的物理仿真行为(顺便添加物理仿真元素)
(3)将物理仿真行为添加到物理仿真器中  开始仿真  

相关说明

1.三个概念
(1)谁要进行物理仿真?
  物理仿真元素(Dynamic Item)
 
(2)执行怎样的物理仿真效果?怎样的动画效果?
  物理仿真行为(Dynamic Behavior) 
 
(3)让物理仿真元素执行具体的物理仿真行为
  物理仿真器(Dynamic Animator)
 
2.物理仿真元素
注意:
不是任何对象都能做物理仿真元素
不是任何对象都能进行物理仿真
 
物理仿真元素要素:
任何遵守了UIDynamicItem协议的对象
UIView默认已经遵守了UIDynamicItem协议,因此任何UI控件都能做物理仿真
UICollectionViewLayoutAttributes类默认也遵守UIDynamicItem协议
 
3.物理仿真行为
(1)UIDynamic提供了以下几种物理仿真行为
UIGravityBehavior:重力行为
UICollisionBehavior:碰撞行为
UISnapBehavior:捕捉行为
UIPushBehavior:推动行为
UIAttachmentBehavior:附着行为
UIDynamicItemBehavior:动力元素行为
 
(2)物理仿真行为须知
上述所有物理仿真行为都继承自UIDynamicBehavior
所有的UIDynamicBehavior都可以独立进行
组合使用多种行为时,可以实现一些比较复杂的效果
 
 
4.物理仿真器
(1)物理仿真器须知
它可以让物理仿真元素执行物理仿真行为
它是UIDynamicAnimator类型的对象
 
(2)UIDynamicAnimator的初始化

  • (instancetype)initWithReferenceView:(UIView *)view;
    view参数:是一个参照视图,表示物理仿真的范围  

5.物理仿真器的说明
(1)UIDynamicAnimator的常见方法
  - (void)addBehavior:(UIDynamicBehavior )behavior;    //添加1个物理仿真行为
  - (void)removeBehavior:(UIDynamicBehavior )behavior;  //移除1个物理仿真行为
  - (void)removeAllBehaviors;    //移除之前添加过的所有物理仿真行为
 
(2)UIDynamicAnimator的常见属性
  @property (nonatomic, readonly) UIView
referenceView;  //参照视图 
  @property (nonatomic, readonly, copy) NSArray
behaviors;//添加到物理仿真器中的所有物理仿真行为
  @property (nonatomic, readonly, getter = isRunning) BOOL running;//是否正在进行物理仿真
  @property (nonatomic, assign) id delegate;//代理对象(能监听物理仿真器的仿真过程,比如开始和结束)

介绍

svn 是多人协同开发的代码管理器,是从大名鼎鼎的代码管理器 CVS 演变
而来,当然除了 svn 外,还有一个流行的代码管理器 git,但是企业中大多喜欢 用 svn,原因是 svn 具有很强的文档目录权限管理,而 git 在开源社区非常流行, git 没有权限管理。

svn 服务端和客户端模型

svn 分为客户端和服务器端 2 中,对于一般开发人员主要使用使用 svn 客户
端,对于项目经理或者 IT 维护组需要进行 svn 服务器端进行诸如代码备份, merge 等操作。
对于 iOS 开发,svn 使用有 2 种。读者个人趋向于 svn 命令行使用 当然更多推荐使用工具 Version: http://192.168.88.8/download/softwares/svn 工具/Versions02.zip 网页版本: http://192.168.88.10/svn
不推荐大家使用 Xcode 自带的 SVN 工具
对于 Versions 不能加入.a 静态库的解决方案
编辑 vi /.subversion/config
找到以 global-ignores 开头的行, 然后去掉里面的 *.a 即可
global-ignores = *.o *.lo *.la *.al .libs *.so .so.[0-9] *.pyc *.pyo *
.nib *.so *.pbxuser .mode .perspective .DS_Store xcuserdata project.xcworkspace
3. svn操作命令之通用参数
–username yang
–password 123456 如果没有用户名和密码就不用此参数
4. svn操作命令之下载checkout(co) svn checkout
svn checkout 是下载代码库
-r 18下载18号版本 例子 1.
svn –username yang –password 123456
checkout http://1000phone.cn/stuproj/ios1212
下载完成后会在当前目录中创建 ios1212 目录
例子 2.
svn –username yang –password 123456
checkout http://1000phone.cn/stuproj/ios1212 myios1212 svn –username yang –password 123456
checkout -r18 http://1000phone.cn/stuproj/ios1212
下载完成后会在当前目录中创建 myios1212 目录
上述 http://1000phone.cn/stuproj/ios1212 是代码服务器网址 这里 checkout 也可以写成 co
5. svn操作命令之查看信息info 比如 svn info
svn info 是查看版本信息
localhost:ios1212 yang$ svn info
Path: .
URL: http://1000phone.cn/stuproj/ios1212
Repository Root: http://1000phone.cn/stuproj
Repository UUID: 489a8e6b-8e7d-4fdf-9695-3480148b3a5a Revision: 10
Node Kind: directory
Schedule: normal
Last Changed Author: yang
Last Changed Rev: 3
Last Changed Date: 2012-11-19 17:28:36 +0800 (Mon, 19 Nov 2012)
6. svn操作命令之查看版本日志信息log svn log
svn log 会显示该目录下面所有的版本信息,按照时间倒序排列 如下面显示:


r1123 | oyangjian | 2012-11-20 21:25:10 +0800 (二, 2012-11-20) | 4 行
增加了 addsvnuser
M common_db.php


r1122 | oyangjian | 2012-11-20 21:24:35 +0800 (二, 2012-11-20) | 4 行
解决了乱码问题
M showcompileinfo.php


r1121 | oyangjian | 2012-11-20 21:23:13 +0800 (二, 2012-11-20) | 4 行
FIX 了修改密码错误情况 M register.php
7. svn操作命令之增加文件add
用法例子(在 xcode 增加文件自动会增加,在 xcode 中写程序不用) svn add RootViewController.m
把 RootViewController.m 文件加入到本地的代码库中
8. svn操作命令之删除文件或者文件夹delete 用法例子(在 xcode 增加文件自动会增加,在 xcode 中写程序不用)
svn delete RootViewController.m 在本地代码库中删除 RootViewController.m 文件
9. svn操作命令之改名文件mv svn mv test.m Car.m
(在 xcode 增加文件自动会增加,在 xcode 中写程序不用) 在本地把 test.m 文件修改成 Car.m 文件
M M A A
Demo/Demo.xcodeproj/project.pbxproj
Demo/Demo/AppDelegate.m Demo/Demo/RootViewController.h Demo/Demo/RootViewController.m
注意上面的 add delete mv 都是在本地代码库中修改
10. svn操作命令之提交变化commit 把本地代码库中所有的修改的内容同步到服务器中 注意不同步的话,本地的修改不能反映到服务器上
svn –username yang –password 123456 commit
11. svn操作命令之同步服务器内容update 把服务器最新版本同步到本地来
svn update
12 svn操作命令之查看patch文件diff
查看任意 2 个版本之间的差异 svn diff –r18:29
13 svn操作命令之查看状态status localhost:yang1212 yang$ svn status
14 svn操作命令之创建目录mkdir svn –username yang –password 123456
mkdir http://1000phone.cn/stuproj/ios1212/test1234 在服务器 ios1212 目录上创建子目录 test1234
15 svn操作命令之导入项目import svn –username yang –password 123456
import myproject http://1000phone.cn/stuproj/ios1212/myproject2 在本机的 myporject 目录传到服务器 ios1212 目录上并且改