H:/1019/01_加速度accelerometer原始方法_AppDelegate.h
//
// AppDelegate.h
// 加速计-01.传统用法
//
// Created by apple on 13-10-19.
// Copyright (c) 2013年 itcast. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
H:/1019/01_加速度accelerometer原始方法_AppDelegate.m
// AppDelegate.m
// 加速计-01.传统用法
// Created by apple on 13-10-19.
// Copyright (c) 2013年 itcast. All rights reserved.
#import "AppDelegate.h"
// 手动导入了MainViewController的头文件
#import "MainViewController.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
// 仅仅加了一句这个,实例化MainViewController
MainViewController *controller = [[MainViewController alloc]init];
[self.window setRootViewController:controller];
[self.window makeKeyAndVisible];
return YES;
}
@end
H:/1019/01_加速度accelerometer原始方法_MainViewController.h
//
// MainViewController.h
// 加速计-01.传统用法
//
// Created by apple on 13-10-19.
// Copyright (c) 2013年 itcast. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface MainViewController : UIViewController
@end
H:/1019/01_加速度accelerometer原始方法_MainViewController.m
// MainViewController.m
// 加速计-01.传统用法
// Created by apple on 13-10-19.
// Copyright (c) 2013年 itcast. All rights reserved.
#import "MainViewController.h"
// 导入第3方框架QuartzCore
#import <QuartzCore/QuartzCore.h>
@interface MainViewController () <UIAccelerometerDelegate>
{
// 小球图像
UIImageView *_ball;
// 小球速度
CGPoint _ballVelocity;
// 游戏时钟 CADisplayLink
CADisplayLink *_gameTimer;
}
@end
@implementation MainViewController
/*
使用DEPRECATED描述符的方法和对象,是不推荐使用的,
同时也是官方停止更新的方法
提示:加速剂默认是不工作,因为工作会耗电,
当设置了采样频率,加速剂开始工作,同时将采样获得的数据
通过代理方法,发送给调用方
UIAcceleration的四个成员说明
* timestamp 数据采样发生的时间,很少用到
* x x 方向的加速度
* y y 方向的加速度
* z z 方向的加速度
*/
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *image = [UIImage imageNamed:@"black.png"];
_ball = [[UIImageView alloc]initWithImage:image];
[_ball setCenter:self.view.center];
[self.view addSubview:_ball];
// 小球初始静止,速度为0
_ballVelocity = CGPointZero;
// 加速计,模板代码
// 1. 实例化加速计,因为在手机上有且仅有一个芯片,因此使用单例来访问加速剂
UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
// 2. 设置更新频率(采样频率HZ)
[accelerometer setUpdateInterval:1 / 30.0];
// 3. 设置代理,为当前控制器
[accelerometer setDelegate:self];
// 游戏时钟 CADisplayLink
// 1. 游戏时钟 实例化 CADisplayLink,同时设置Target对象的selector方法
_gameTimer = [CADisplayLink displayLinkWithTarget:self
selector:@selector(step)];
// 2. 游戏时钟 添加到主运行循环,使用默认模式
[_gameTimer addToRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];
}
#pragma mark - 时钟监听方法
- (void)step
{
//调用自定义方法,更新小球坐标
[self updateBallLocation];
}
#pragma mark - 自定义方法,更新小球位置
- (void)updateBallLocation
{
// 根据小球位置调整中心点位置
CGPoint center = _ball.center;
// 判断小球的位置是否超出边界,如果超出边界,将小球的方向求反
// 1) 水平方向
// 如果小球的最小x值,小于0,表示左边出界
// CGRectGetMinX(_ball.frame) = _ball.frame.origin.y
// 如果小球的最大x值,大于viewW,表示右边边出界
if (CGRectGetMinX(_ball.frame) < 0 ||
CGRectGetMaxX(_ball.frame) > self.view.bounds.size.width) {
// 0.8 模拟速度衰减系数
_ballVelocity.x *= -0.8;
// 修复小球位置,防止嵌入边框,贴在边框上,动不了
if (CGRectGetMinX(_ball.frame) < 0) {
center.x = _ball.bounds.size.width / 2;
} else {
center.x = self.view.bounds.size.width - _ball.bounds.size.width / 2;
}
}
// 2)垂直方向
if (CGRectGetMinY(_ball.frame) < 0 ||
CGRectGetMaxY(_ball.frame) > self.view.bounds.size.height) {
_ballVelocity.y *= -0.8;
// 修复小球位置,防止嵌入边框,贴在边框上,动不了
if (CGRectGetMinY(_ball.frame) < 0) {
center.y = _ball.bounds.size.height / 2;
} else {
center.y = self.view.bounds.size.height - _ball.bounds.size.height / 2;
}
}
center.x += _ballVelocity.x;
center.y += _ballVelocity.y;
// 由于时钟被添加到主运行循环中,故可以直接更新UI
[_ball setCenter:center];
}
#pragma mark - 加速计代理方法
- (void)accelerometer:(UIAccelerometer *)accelerometer
didAccelerate:(UIAcceleration *)acceleration
{
// 使用加速度调整小球速度,开发中,v=v0+a*t,t是恒定的,a是变化的???
_ballVelocity.x += acceleration.x;
// 加速计的Y轴和UIKit的Y轴相反,故
_ballVelocity.y -= acceleration.y;
// 让加速剂仅负责采样数据,更新速度
// [self updateBallLocation];
}
@end
H:/1019/02_CoreMotion框架_单例_时钟_AppDelegate.h
// AppDelegate.h
// 加速计-CM Push
// Created by apple on 13-10-19.
// Copyright (c) 2013年 itcast. All rights reserved.
#import <UIKit/UIKit.h>
// CMMotionManager单例方式1:第1步:导入框架
#import <CoreMotion/CoreMotion.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
// CMMotionManager单例方式1:第2步:定义成员,只有getter
// 运动管理器的单例
@property (strong, nonatomic, readonly) CMMotionManager *sharedMotionManager;
@end
H:/1019/02_CoreMotion框架_单例_时钟_AppDelegate.m
// AppDelegate.m
// 加速计-CM Push
// Created by apple on 13-10-19.
// Copyright (c) 2013年 itcast. All rights reserved.
#import "AppDelegate.h"
#import "MainViewController.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
//加了这一句话,实例化MainViewController
MainViewController *controller = [[MainViewController alloc]init];
[self.window setRootViewController:controller];
[self.window makeKeyAndVisible];
return YES;
}
// CMMotionManager单例方式1:第3步:使用静态对象记录住第一次被初始化的实例
static CMMotionManager *montionManager;
// CMMotionManager单例方式1:第4步:实现getter方法
- (CMMotionManager *)sharedMotionManager
{
// 使用dispatch_once GCD生成单例对象
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
montionManager = [[CMMotionManager alloc]init];
});
return montionManager;
}
@end
H:/1019/02_CoreMotion框架_单例_时钟_MainViewController.h
//
// MainViewController.h
// 加速计-CM Push
//
// Created by apple on 13-10-19.
// Copyright (c) 2013年 itcast. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface MainViewController : UIViewController
@end
H:/1019/02_CoreMotion框架_单例_时钟_MainViewController.m
// MainViewController.m
// 加速计-CM Push
// Created by apple on 13-10-19.
// Copyright (c) 2013年 itcast. All rights reserved.
#import "MainViewController.h"
#import <CoreMotion/CoreMotion.h>
// 需求4:使用时钟更新,步骤1,导入QuartzCore
#import <QuartzCore/QuartzCore.h>
//#import "AppDelegate.h" 使用方式2,会产生嵌套引用问题,不推荐
#import "MyMotionManager.h" // 推荐使用方式3
@interface MainViewController ()
{
UIImageView *_ball; // 小球
CGPoint _ballVelocity; // 小球速度
CMMotionManager *_montionManager; // 运动管理器(单例)
// 操作队列,耗时的操作不要放到主队列里面,新建一个操作队列
NSOperationQueue *_queue;
// 需求4:使用时钟更新,步骤2,成员变量:CADisplayLink
CADisplayLink *_gameTimer; // 游戏时钟
}
@end
@implementation MainViewController
/*
accelerometerAvailable 加速计计是否可用
accelerometerUpdateInterval 加速计采样频率
accelerometerActive 加速计是否正在采样数据
accelerometerData 取回末次采样数据,pull方法使用
startAccelerometerUpdates 开始加速计更新
startAccelerometerUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMAccelerometerHandler)handler
使用多线程的加速计采样数据,push方法
stopAccelerometerUpdates 停止采样
*/
- (void)viewDidLoad
{
[super viewDidLoad];
// 实例化小球
UIImage *image = [UIImage imageNamed:@"black.png"];
_ball = [[UIImageView alloc]initWithImage:image];
[_ball setCenter:self.view.center];
[self.view addSubview:_ball];
// 操作队列,耗时的操作不要放到主队列里面,新建一个操作队列
_queue = [[NSOperationQueue alloc]init];
// 调用自定义方法,加载加速计
[self loadAccelerometerData];
// 需求4:使用时钟更新,步骤3,实例化时钟,并加到主运行队列mainRunLoop
_gameTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(step)];
[_gameTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
#pragma mark - 加速计采样数据
- (void)loadAccelerometerData
{
// 运动管理器生成方式1: 直接实例化,
// 缺点:如果应用程序中有多个视图控制器需要使用加速计,无法让加速计共享
//_montionManager = [[CMMotionManager alloc]init];
// 运动管理器生成方式2: 从AppDelegate中getter方法获取运动管理器的单例
// 1> 只需要在AppDelegate中定义即可,因为UIApplication本身就是一个单例
// 2> 缺点:会出现.h文件嵌套引用的问题,在实际开发中,应该尽量避免
// 3.1> 先获取AppDelegate单例
//AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
// 3.2> 通过getter方法获得返回
//CMMotionManager *_montionManager = [appDelegate sharedMotionManager];
// 运动管理器生成方式3: 自己定义一个类继承CMMotionManager,
//从MyMotionManager的类方法中获取提供的运动管理器的单例
_montionManager = [MyMotionManager sharedMontionManager];
// 采样过程
// 1) 判断加速计是否可用
if ([_montionManager isAccelerometerAvailable]) {
// 2) 指定加速计采样频率
[_montionManager setAccelerometerUpdateInterval:1 / 30.0];
// 调用自定义的方法,开始采样
[self accelerometerUpdatesData];
} else {
NSLog(@"加速计不可用");
}
}
// 需求4:使用时钟更新,步骤4,时钟任务,仅是更新小球位置
#pragma mark - 模板代码,直接剪切过来的,更新小球位置
- (void)step
{
// 根据小球位置调整中心点位置
CGPoint center = _ball.center;
// 判断小球的位置是否超出边界,如果超出边界,将小球的方向求反
// 1) 水平方向
// 如果小球的最小x值,小于0,表示左边出界
// CGRectGetMinX(_ball.frame) = _ball.frame.origin.y
// 如果小球的最大x值,大于viewW,表示右边边出界
if (CGRectGetMinX(_ball.frame) < 0 || CGRectGetMaxX(_ball.frame) > self.view.bounds.size.width) {
_ballVelocity.x *= -0.8;
// 修复小球位置
if (CGRectGetMinX(_ball.frame) < 0) {
center.x = _ball.bounds.size.width / 2;
} else {
center.x = self.view.bounds.size.width - _ball.bounds.size.width / 2;
}
}
// 2)垂直方向
if (CGRectGetMinY(_ball.frame) < 0 || CGRectGetMaxY(_ball.frame) > self.view.bounds.size.height) {
_ballVelocity.y *= -0.8;
// 修复小球位置
if (CGRectGetMinY(_ball.frame) < 0) {
center.y = _ball.bounds.size.height / 2;
} else {
center.y = self.view.bounds.size.height - _ball.bounds.size.height / 2;
}
}
center.x += _ballVelocity.x;
center.y += _ballVelocity.y;
/* 如果这儿采用了多线程,则更新界面UI要在主线程中完成
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
[_ball setCenter:center];
}];*/
// 如果,这儿是时钟要在主线程中,执行的任务,可直接更新位置
[_ball setCenter:center];
}
#pragma mark - 自定义方法,抽取出来的,开始采样数据
// 加速计更新数据
- (void)accelerometerUpdatesData
{
// 3) 使用push方法,采样数据
// 注意:参数1为操作队列,耗时的操作不要放到主队列里面,新建一个操作队列
[_montionManager startAccelerometerUpdatesToQueue:_queue
withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
// 由于参数1,不是主线程,而是一个单独的操作队列,
// 所以,这儿仅负责更新小球的速度,不提供更新小球位置UI
// 而是由时钟的target 的selector方法中更新UI即小球位置
_ballVelocity.x += accelerometerData.acceleration.x;
_ballVelocity.y -= accelerometerData.acceleration.y;
}];
}
#pragma mark - 触摸事件
// 点按屏幕停止数据更新,游戏中有暂停的需求
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// 提示,加速计负责采样数据,游戏时钟负责更新界面
// 因此,暂停游戏时,需要将二者同时暂停或启动
// 根据加速计是否正在采样数据,停止或者开始采样数据
if ([_montionManager isAccelerometerActive]) {
// 停止采样
[_montionManager stopAccelerometerUpdates];
// 由于是时钟负责更新小球位置UI,故还需要停止游戏时钟
// 停止时钟方式1:invalidate方法会销毁游戏时钟,
// 下次启动时,需要重新实例化,不划算,高耗
// [_gameTimer invalidate];
// 停止时钟方式2:将游戏时钟从主运行循环中移除,对象没被销毁
// 下次启动时,无需实例化gameTimer
[_gameTimer removeFromRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];
} else {
// 开始采样
[self accelerometerUpdatesData];
// 重新开启游戏时钟方式1:再次实例化一个,再加到主运行循环中
// _gameTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(step)];
// 如果前面停止时钟的时候,没有将时钟销毁,
// 仅是从主运行循环中移除,则再次添加即可,无需重新实例化
[_gameTimer addToRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];
}
}
@end
H:/1019/02_CoreMotion框架_单例_时钟_MyMotionManager.h
//
// MyMotionManager.h
// 加速计-CM Push
//
// Created by apple on 13-10-19.
// Copyright (c) 2013年 itcast. All rights reserved.
//
// CMMotionManager单例方式3:第1步:导入框架
#import <CoreMotion/CoreMotion.h>
// CMMotionManager单例方式3:第2步:继承CMMotionManager
@interface MyMotionManager : CMMotionManager
// CMMotionManager单例方式3:第3步:类方法,返回MyMotionManager对象
+ (MyMotionManager *)sharedMontionManager;
@end
H:/1019/02_CoreMotion框架_单例_时钟_MyMotionManager.m
// MyMotionManager.m
// 加速计-CM Push
// Created by apple on 13-10-19.
// Copyright (c) 2013年 itcast. All rights reserved.
#import "MyMotionManager.h"
@implementation MyMotionManager
// CMMotionManager单例方式3:第4步:使用静态对象记录住第一次被初始化的实例
// 单例模式:标准步骤1:静态的对象记录住第一次被实例化的对象
static MyMotionManager *sharedInstance;
/*
重点!!!! OC中单例设计模式 标准三步曲
1. 静态的对象记录住第一次被实例化的对象
2. 重写allocWithZone类方法
3. 提供一个shared方法,方便其他类调用
*/
// 单例模式:标准步骤2:重写父类的allocWithZone类方法,分配内存区块
+ (id)allocWithZone:(NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 调用父类的allocWithZone方法,对象实例化
sharedInstance = [super allocWithZone:zone];
});
return sharedInstance;
}
// CMMotionManager单例方式3:第5步:实现getter方法
// 单例模式:标准步骤3:提供一个shared方法,方便其他类调用
+ (MyMotionManager *)sharedMontionManager
{
// 使用dispatch_once GCD生成单例对象,并返回
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 调用父类的方法初始化,(内部自动调用上面的allocWithZone)
sharedInstance = [[super alloc]init];
});
return sharedInstance;
}
@end
H:/1019/03_Get+异步请求+Json+AppDelegate.h
//
// AppDelegate.h
// 蘑菇街JSON
//
// Created by apple on 13-10-14.
// Copyright (c) 2013年 itcast. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
H:/1019/03_Get+异步请求+Json+AppDelegate.m
// AppDelegate.m
// 蘑菇街JSON
// Created by apple on 13-10-14.
// Copyright (c) 2013年 itcast. All rights reserved.
#import "AppDelegate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
// 1. URL
NSString *str = @"http://www.mogujie.com/app_mgj_v511_book/clothing?_adid=5503509D-800B-45EF-B767-F6586FFF165E&_did=0f607264fc6318a92b9e13c65db7cd3c&_atype=iPhone&_source=NIMAppStore511&_fs=NIMAppStore511&_swidth=640&_network=2&_mgj=8383caabf1c61a55a96c29262b7beff61381734506&title=最热&from=hot_element&login=false&fcid=6550&q=最热&track_id=1377824666&homeType=shopping";
NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
// 2. Request
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3. Connection异步
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *reponse, NSData *data, NSError *error) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments error:nil];
// 4. 保存数据
[dict writeToFile:@"/Users/apple/Desktop/123.plist" atomically:YES];
}];
[self.window makeKeyAndVisible];
return YES;
}
@end