传统加速器的使用和蓝牙的使用

来源:互联网 发布:泳装的销售数据 编辑:程序博客网 时间:2024/04/29 11:39




//加速器的使用
@implementation HMViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 1.获得单例对象(过期:不再更新,并不一定代表不能用)
    UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
    
    // 2.设置代理
    accelerometer.delegate = self;
    
    // 3.设置采样间隔(每隔多少秒采样一次数据)
    accelerometer.updateInterval = 1 / 30.0;
}


#pragma mark - UIAccelerometerDelegate
/**
 *  当采样到加速计数据时,就会调用一次(调用频率一般比较高)
 */
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    // 1.累加速度
    // v = a * t = a1 + a2 + a3 + ...... + at
    _velocity.x += acceleration.x;
    _velocity.y -= acceleration.y;
    
    // 2.累加位移
    // s = v * t = v1 + v2 + v3 + ...... + vt
    self.ball.x += _velocity.x;
    self.ball.y += _velocity.y;
    
    // 3.边界判断
    if (self.ball.x <= 0) { // x超出屏幕左边
        self.ball.x = 0;
        // 速度取反,削弱速度
        _velocity.x *= -0.5;
    }
    if (self.ball.maxX >= self.view.width) { // x超出屏幕右边
        self.ball.maxX = self.view.width;
        
        // 速度取反,削弱速度
        _velocity.x *= -0.5;
    }
    if (self.ball.y <= 0) { // y超出屏幕上边
        self.ball.y = 0;
        // 速度取反,削弱速度
        _velocity.y *= -0.5;
    }
    if (self.ball.maxY >= self.view.height) { // y超出屏幕下边
        self.ball.maxY = self.view.height;
        // 速度取反,削弱速度
        _velocity.y *= -0.5;
    }
}
@end






//距离传感器的使用
@interface ViewController ()


@end


@implementation ViewController


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
//    [UIApplication sharedApplication].proximitySensingEnabled = YES;
    [UIDevice currentDevice].proximityMonitoringEnabled = YES;
    
    // 监听距离改变
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(proximityStateDidChange:) name:UIDeviceProximityStateDidChangeNotification object:nil];
}


- (void)proximityStateDidChange:(NSNotification *)note
{
    if ([UIDevice currentDevice].proximityState) {
        NSLog(@"有物体靠近");
    }else
    {
        NSLog(@"物理离开");
    }
}


@end




//蓝牙连接代码
/*
 > 讲解相片选择器
 *先不设置代理,创建后直接运行
 *从选择相片后需要关闭控制器引出代理
 *实现代理方法展示数据
 *PPT讲解蓝牙连接(不是所有应用都可以用蓝牙传输东西,必须相同应用事先写好如何处理. 苹果蓝牙传输非常满, 而且传输过程中没有进度)
 *在storyboard中添加按钮, 点击按钮后创建对端选择控制器, 设置代理,显示视图控制器
 *在代理方法中打印peerID, 讲解session用途查看头文件引出利用传递数据
 *定义属性保存session , 在storyboard中添加按钮监听按钮点击利用session传递图片
 *讲解传递数据方法两种模式区别
 *设置数据处理者, 讲解如何找到数据处理方法,在数据处理方法中打印LOG运行验证
 *将接收到的数据转换为图片后现实在界面上
 *总结蓝牙传输
 */


#import "CZViewController.h"
#import <GameKit/GameKit.h>


@interface CZViewController ()<UIImagePickerControllerDelegate, UINavigationControllerDelegate, GKPeerPickerControllerDelegate>


/**
 * 现实相片
 */
- (IBAction)selectPhoto;


@property (weak, nonatomic) IBOutlet UIImageView *imageView;


/**
 * 蓝牙连接
 */
- (IBAction)connectBtnClick;


/**
 * 会话对象
 */
@property (nonatomic, strong)GKSession *session;


/**
 * 发送相片
 */
- (IBAction)sendPhoto;


@end


@implementation CZViewController


#pragma mark 选择照片
/*
 照片源类型
 
 UIImagePickerControllerSourceTypeCamera            照相机
 UIImagePickerControllerSourceTypePhotoLibrary      照片库(通过同步存放的,用户不能删除)
 UIImagePickerControllerSourceTypeSavedPhotosAlbum  保存的照片(通过拍照或者截屏保存的,用户可以删除)
 */
- (IBAction)selectPhoto
{
    
    
    // 1.判断照片源是否可用
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
        // 1.1实例化控制器
        UIImagePickerController *picker = [[UIImagePickerController alloc] init];
        // 1.2设置照片源
        [picker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
        // 1.3设置允许修改
        picker.allowsEditing = YES;
        // 1.4设置代理
        picker.delegate = self;
        // 1.5显示控制器
        [self presentViewController:picker animated:YES completion:^{
            
        }];
    }else
    {
        // 2.照片源不可用
        NSLog(@"照片源不可用");
    }
}


#pragma mark - imagePicker代理方法
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
//    NSLog(@"%@", info);
    // 获取相片
    UIImage *image = info[@"UIImagePickerControllerEditedImage"];
    // 设置相片
    self.imageView.image = image;
    
    // 关闭相片选择器
    [self dismissViewControllerAnimated:YES completion:^{
        
    }];
    
    
}


#pragma mark - 蓝牙连接
- (IBAction)connectBtnClick
{
    // 1.创建对端选择控制器
    GKPeerPickerController *picker = [[GKPeerPickerController alloc] init];
    
    // 2.设置代理
    picker.delegate = self;
    
    // 3.显示试图控制器
    [picker show];
    
}


#pragma mark - GKPeerPickerControllerDelegate
// 完成对端连接
// GKSession对象用于表现两个蓝牙设备之间连接的一个会话,你也可以使用它在两个设备之间发送和接收数据。
- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session
{
    NSLog(@"连接成功 %@", peerID);
    // 保存会话
    self.session = session;
    
     // 设置数据处理对象,类似于delegate
    [self.session setDataReceiveHandler:self withContext:nil];
    
    // 关闭对端选择控制器
    [picker dismiss];
}


// 取消对端选择控制器
- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker
{
    NSLog(@"取消蓝牙选择器");
}


// 发送相片
- (IBAction)sendPhoto {
    
    NSData *imageData = UIImagePNGRepresentation(self.imageView.image);
    
    // 利用session发送相片
//    self.session sendData:<#(NSData *)#> toPeers:<#(NSArray *)#> withDataMode:<#(GKSendDataMode)#> error:<#(NSError *__autoreleasing *)#>
    /*
     TCP协议、UDP协议
     
     1. 要发送的数据(二进制的)
     2. 数据发送模式
     GKSendDataReliable      :确保数据发送成功(TCP协议,对网络压力大)
     GKSendDataUnReliable    :只管发送不管成功(UDP协议,对数据完整性要求不高,对网络压力下)
     */
    [self.session sendDataToAllPeers:imageData withDataMode:GKSendDataReliable error:nil];
    
}




// 数据接受处理方法,此方法需要从文档中粘贴出来,没有智能提示
- (void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
{
    NSLog(@"接收到数据");
     // 将NSData转换成UIImage
    UIImage *image = [UIImage imageWithData:data];
    self.imageView.image = image;
}


/*
 关于蓝牙的数据传输
 
 1. 一次性传送,没有中间方法,所谓中间方法值得是,传输进度比例
 对于用户而言,选择了传输,就需要等待传输完成,或者传输以失败告终
 这就意味着,在实际开发过程中,最好不要用蓝牙传输太大的文件
 
 在实际应用中,蓝牙通常用于传递游戏数据模型,用于联机对战,譬如点对点的棋牌类游戏。
 */


@end




//加速器的使用方式
@implementation HMViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 1.创建motion管理者
    self.mgr = [[CMMotionManager alloc] init];
    
    // 2.判断加速计是否可用
    if (self.mgr.isAccelerometerAvailable) {
        [self pull];
    } else {
        NSLog(@"---加速计不可用-----");
    }
}
/**
 * ******* pull *******
 */
- (void)pull
{
    [self.mgr startAccelerometerUpdates];
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    CMAcceleration acceleration = self.mgr.accelerometerData.acceleration;
    NSLog(@"%f %f %f", acceleration.x, acceleration.y, acceleration.z);
}


/**
 * ******* push *******
 */
- (void)push
{
    // 3.设置采样间隔
    self.mgr.accelerometerUpdateInterval = 1 / 30.0;
    
    // 4.开始采样(采集加速度数据)
    [self.mgr startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
        // 如果在block中执行较好时的操作,queue最好不是主队列
        // 如果在block中要刷新UI界面,queue最好是主队列
        NSLog(@"%f %f %f", accelerometerData.acceleration.x, accelerometerData.acceleration.y, accelerometerData.acceleration.z);
    }];
}


@end




//传统加速器的使用
/*
 > 加速计
 *PPT介绍加速计, 加速计属于传感器的范畴...
 *新建项目讲解加速计的传统使用
 *查看Accelerometer头文件, 讲解Accelerometer头文件中的属性引出为什么过时了还那么多人用(简单, 查看头文件)
 *从代理方法参数引出定义属性保存小球加速度(CGPoint), 并在代理方法中设置小球的位置
 *Vt = V0 + a * t (最终速度 = 初始速度 + 加速度 * 时间)
 Vt = V0 + g * t (加速度是恒定的9.8)
 Vt = V0 + g1 + g2 + g3 … (时间和加速度都是恒定的)
 Vt = V0 + a1 + a2 + a3 … (手机中时间是恒定的, 加速度不是恒定的)
 *从小球移除频幕看不到引出画图讲解边界检测(碰撞检测)
 *从小球会贴在边框出不来引出画图讲解如何解决(移动小球的位置到边界再加速度)
 *讲解为什么用两个if 不用else if, 小球在四个角的情况
 */


#import "CZViewController.h"


@interface CZViewController ()<UIAccelerometerDelegate>
/**
 * 小球
 */
@property (nonatomic, weak)UIImageView *ballIv;
/**
 * 保存x y方向加速度
 */
@property (nonatomic, assign)CGPoint ballVelocity;


@end


@implementation CZViewController


- (void)viewDidLoad
{
    [super viewDidLoad];


    // 1.添加小球
    UIImage *image = [UIImage imageNamed:@"black"];
    UIImageView *iv = [[UIImageView alloc] initWithImage:image];
    [self.view addSubview:iv];
    self.ballIv = iv;
    
    // 2.获得加速计单例
    /**
     updateInterval     更新间隔(采样,采集数据样本)
     delegate           代理
     */
    UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
    // 设置采样时间
    accelerometer.updateInterval = 1 / 30.0;
    // 设置代理
    accelerometer.delegate = self;
}


#pragma mark - UIAccelerometerDelegate
// UIAcceleration 加速度
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    // 1. 记录小球加速度
    _ballVelocity.x += acceleration.x;
     // 加速计y轴方向和UIKit坐标相反
    _ballVelocity.y -= acceleration.y;
    
    // 2.更新小球位置
    [self updateLocation];
}


- (void)updateLocation
{
    // 设置小球的位置
    CGPoint center = self.ballIv.center;
    CGSize size = self.view.bounds.size;
    
    // 解决小球出界问题,碰撞检测
    // 水平方向:左边,右边
    if (CGRectGetMinX(self.ballIv.frame) <= 0 || CGRectGetMaxX(self.ballIv.frame) >= size.width) {
        // 修改小球的速度方向
        _ballVelocity.x *= -1;
        
        // 修复位置 < 0
        if (CGRectGetMinX(self.ballIv.frame) <= 0) {
            center.x = self.ballIv.bounds.size.width / 2.0;
        } else {
            center.x = size.width - self.ballIv.bounds.size.width / 2.0;
        }
    }
    
    // 垂直方向
    if (CGRectGetMinY(self.ballIv.frame) <= 0 || CGRectGetMaxY(self.ballIv.frame) >= size.height) {
        // 修改小球的速度方向
        _ballVelocity.y *= -1;
        
        // 修复位置 < 0
        if (CGRectGetMinY(self.ballIv.frame) <= 0) {
            center.y = self.ballIv.bounds.size.height / 2.0;
        } else {
            center.y = size.height - self.ballIv.bounds.size.height / 2.0;
        }
    }
    
    center.x += _ballVelocity.x;
    center.y += _ballVelocity.y;
    
    self.ballIv.center = center;
}


@end




#import "CZMotionManager.h"


/**
 1. 静态的全局实例
 2. allocWithZone
 3. 定义一个shared方法,供全局使用
 */


// 保存当前类的实例
static CZMotionManager *_instance;


@implementation CZMotionManager


+ (instancetype)shareMotionManager
{
    if (_instance == nil) {
        _instance  = [[[self class] alloc] init];
    }
    return _instance;
}


#pragma mark - 以下方法是为了保证对象在任何情况下都唯一
//    调用alloc的时候会调用这个方法
+ (id)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    //  保证我们的block只能执行一次
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}
//会在调用copy的时候调用这个方法
- (id)copyWithZone:(NSZone *)zone
{
    return self;
}


//在调用mutableCopy的时候调用这个方法
- (id)mutableCopyWithZone:(NSZone *)zone
{
    return self;
}




@end




//摇一摇
@implementation HMViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    Class c = NSClassFromString(@"UINavigationTransitionView");
    
    UIView *view =  [[c alloc] init];
    
    NSLog(@"%@", view);
//    UINavigationController *nav = [[UINavigationController alloc] init];
//    NSLog(@"%@", nav.view.subviews);
}


#pragma mark - 实现相应的响应者方法
/** 开始摇一摇 */
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    NSLog(@"motionBegan");
}


/** 摇一摇结束(需要在这里处理结束后的代码) */
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    // 不是摇一摇运动事件
    if (motion != UIEventSubtypeMotionShake) return;
    
    NSLog(@"motionEnded");
}


/** 摇一摇取消(被中断,比如突然来电) */
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    NSLog(@"motionCancelled");
}
@end























0 0
原创粉丝点击