一.加速計
加速計的作用
● 用於檢測設備的運動(比如搖晃)
加速計的經典應用場景
● 搖一搖
● 計步器
加速計的原理
●檢測設備在X、Y、Z軸上的加速度 (哪個方向有力的作用,哪個方向運動了)
●根據加速度數值,就可以判斷出在各個方向上的作用力度
各個方向上,加速度的大小如下( 加速度的取值在 (-1,1) 之間
加速計程序的開發
●加速計程序的開發
● 在iOS5以前:使用UIAccelerometer,用法非常簡單
●從iOS5開始:CoreMotion.framework
●雖然UIAccelerometer已經過期,但由於其用法極其簡單,很多程序裏面都還有殘留
1.使用UIAccelerometer實現手機晃動的時候,小球的位置都是跟着重力的往下掉,並且碰到屏幕邊緣回彈
UIAccelerometer的使用代碼如下:// HMViewController.m
#import "HMViewController.h"
#import "UIView+Extension.h"
@interface HMViewController () <UIAccelerometerDelegate>
@property (weak, nonatomic) IBOutlet UIImageView *ball;
@property (nonatomic, assign) CGPoint velocity;
@end
@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
晃動手機的時候效果圖如下:2.CoreMotion.framework的使用
①.CoreMotion簡介
②.push和pull的區別
使用代碼如下:
// HMViewController.m
#import "HMViewController.h"
#import <CoreMotion/CoreMotion.h>
@interface HMViewController ()
@property (nonatomic, strong) CMMotionManager *mgr;
@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
3.搖一搖的功能實現
使用iOS自帶的shake搖晃的API實現,只要是響應者就能監聽這方法
代碼如下:// HMViewController.m
#import "HMViewController.h"
@interface HMViewController ()
@end
@implementation HMViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
#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
二.傳感器
1.傳感器介紹
● 傳感器是一種感應\檢測裝置,目前已經廣泛應用於智能手機上
● 傳感器的作用
● 用於感應\檢測設備周邊的信息
● 不同類型的傳感器,檢測的信息也不一樣
● iPhone中的下面現象都是由傳感器完成的
● 在地圖應用中,能判斷出手機頭面向的方向
● 一關燈, iPhone會自動降低亮度讓屏幕顯得不是那麼刺眼
● 打電話時,人臉貼近iPhone屏幕時,屏幕會自動鎖屏,達到省電的目的
傳感器的類型
● 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設備會自動調低亮度,讓屏幕顯得不再那麼光亮刺眼
● 幾乎所有的Mac都帶有背光鍵盤,當週圍光線弱到一定條件時,會自動開啓鍵盤背光
距離傳感 (Proximity Sensor)
● 當你打電話或接電話時將電話屏幕貼近耳邊,iPhone會自動關閉屏幕 ,好處是
● 節省電量
● 防止耳朵或面部不小心觸摸屏幕而引發一些不想要的意外操作
磁力計傳感 (Magnetometer Sensor)
●可以感應地球磁場, 獲得方向信息, 使位置服務數據更精準●可以用於電子羅盤和導航應用
● iPad的Smart Cover盒蓋睡眠操作就是基於磁力計傳感器
內部溫度傳感 (Internal Temperature Sensor)
● 從iPad一代開始,iOS設備都加入了一個內部溫度傳感器,用於檢測內部組件溫度,當溫度超過系統設定的閾值時,會出現以下提示
●內部溫度傳感器,對於提升iOS設備自身安全性與穩定性有很大的幫助
溼度傳感 (Moisture Sensor)
● 溼度傳感器跟其他基於微電子的傳感器不同,是一個簡單的物理傳感器
●簡單來說,溼度傳感器就是一張遇水變紅的試紙
● Apple的維修人員就是通過檢測試紙是否變紅,來判斷設備是否進水
● 陀螺儀是隨着iPhone4的上市首次出現在iOS設備上的傳感器
● 陀螺儀可以用於檢測設備的持握方式
● 陀螺儀的原理是檢測設備在X、Y、Z軸上所旋轉的角速度
● 陀螺儀在賽車類遊戲中有重大作用
●模擬汽車駕駛時方向盤旋轉的動作
● 使得這類遊戲的操控體驗更爲真實
運動傳感\加速度傳感\加速計(Motion/Accelerometer Sensor)
●最早出現在iOS設備上的傳感器之一
●加速計用於檢測設備在X、Y、Z軸上的加速度 (哪個方向有力的作用)
●加速計可以用於檢測設備的搖晃,經典應用場景
搖一搖 計步器
距離傳感器的使用:
// HMViewController.m
#import "HMViewController.h"
@interface HMViewController ()
@end
@implementation HMViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// 打開距離傳感器,開啓距離檢測功能
// [UIApplication sharedApplication].proximitySensingEnabled = YES; 過期
[UIDevice currentDevice].proximityMonitoringEnabled = YES;
// 監聽距離改變
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(proximityStateDidChange:) name:UIDeviceProximityStateDidChangeNotification object:nil];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)proximityStateDidChange:(NSNotification *)note
{
if ([UIDevice currentDevice].proximityState) {
NSLog(@"有物體靠近設備屏幕");
} else {
NSLog(@"有物體遠離設備屏幕");
}
}
@end
三.藍牙
iOS中藍牙的實現方案
1.GameKit的使用
要求:在模擬器和真機家裏連接,選擇真機裏的圖片.顯示到imageView上,點擊發送,發送到模擬器上,模擬器把圖片保存到相冊
如下圖:
代碼如下:
// HMViewController.m
#import "HMViewController.h"
#import <GameKit/GameKit.h>
@interface HMViewController () <GKPeerPickerControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (nonatomic, strong) GKSession *session;
- (IBAction)buildConnect;
- (IBAction)sendData;
//點擊imageView的手勢
- (IBAction)selectImage:(UITapGestureRecognizer *)sender;
@end
@implementation HMViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
//建立連接
- (IBAction)buildConnect {
// 1.創建設備列表控制器
GKPeerPickerController *ppc = [[GKPeerPickerController alloc] init];
// 2.設置代理
ppc.delegate = self;
// 3.顯示控制器
[ppc show];
}
//發送數據
- (IBAction)sendData {
if (self.imageView.image == nil) return;
// 壓縮圖片數據
NSData *data = UIImagePNGRepresentation(self.imageView.image);
// Pet *p = [];
// NSData *data = [NSKeyedArchiver archivedDataWithRootObject:p];
// 發送數據
[self.session sendDataToAllPeers:data withDataMode:GKSendDataReliable error:nil];
}
//點擊imageView的的手勢
- (IBAction)selectImage:(UITapGestureRecognizer *)sender {
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;
// 1.創建圖片選擇控制器
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
// 2.設置代理
ipc.delegate = self;
// 3.顯示
[self presentViewController:ipc animated:YES completion:nil];
}
#pragma mark - 監聽圖片選擇
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// 1.銷燬圖片選擇控制器
[picker dismissViewControllerAnimated:YES completion:nil];
// 2.顯示圖片
self.imageView.image = info[UIImagePickerControllerOriginalImage];
}
#pragma mark - GKPeerPickerControllerDelegate
/**
* 連接到某個設備就會調用
*
* @param peerID 設備的藍牙ID
* @param session 連接會話(通過session傳輸和接收數據)
*/
- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session
{
// 1.銷燬顯示設備的控制器
[picker dismiss];
// 2.保存session
self.session = session;
// 3.處理接收的數據(接收到藍牙設備傳輸的數據時,就會調用self的receiveData:fromPeer:inSession:context:)
[self.session setDataReceiveHandler:self withContext:nil];
}
#pragma mark - 接收到藍牙設備傳輸的數據,就會調用
- (void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context
{
self.imageView.image = [UIImage imageWithData:data];
// 寫入相冊
UIImageWriteToSavedPhotosAlbum(self.imageView.image, nil, nil, nil);
}
@end
2.CoreBluetooth的使用
①.CoreBluetooth
②.核心類
③.CoreBuletooth基本常識
④.開發步驟
代碼實現步驟如下:
// HMViewController.m
#import "HMViewController.h"
#import <CoreBluetooth/CoreBluetooth.h>
@interface HMViewController () <CBCentralManagerDelegate, CBPeripheralDelegate>
@property (nonatomic, strong) CBCentralManager *mgr;
@property (nonatomic, strong) NSMutableArray *peripherals;
@property (nonatomic, strong) CBCharacteristic *dataInteractCharacteristic;
@property (nonatomic, strong) CBCharacteristic *peripheralInfoCharacteristic;
@end
@implementation HMViewController
- (NSMutableArray *)peripherals
{
if (!_peripherals) {
self.peripherals = [NSMutableArray array];
}
return _peripherals;
}
- (CBCentralManager *)mgr
{
if (!_mgr) {
// 1.創建中心設備管理者,用來管理中心設備
self.mgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
return _mgr;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// 2.掃描外設
#warning 通過傳入一個存放服務UDID的數組進去,過濾掉一些不要的外設
[self.mgr scanForPeripheralsWithServices:@[@"434", @"435435"] options:nil];
}
/**
* 3.點擊按鈕,建立連接
*/
- (void)buildConnect
{
for (CBPeripheral *peripheral in self.peripherals) {
[self.mgr connectPeripheral:peripheral options:nil];
}
}
#pragma mark - CBCentralManagerDelegate
/**
* 掃描後,發現外圍設備的時候調用
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
// 添加外圍設備
if (![self.peripherals containsObject:peripheral]) {
// 設置外設的代理
peripheral.delegate = self;
[self.peripherals addObject:peripheral];
}
}
/**
* 連接到某個外設的時候調用
*/
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
// 查找外設中的所有服務
#warning 通過傳入一個存放服務UDID的數組進去,過濾掉一些不要的服務
[peripheral discoverServices:@[@"434", @"435435"]];
}
/**
* 跟某個外設失去連接
*/
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
}
#pragma mark - CBPeripheralDelegate
/**
* 外設已經查找到服務
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
// 遍歷所有的服務
for (CBService *service in peripheral.services) {
// 過濾掉不想要的服務
if ([service.UUID isEqual:@"123"]) {
// 找到想要的服務
// 掃描服務下面的特徵
#warning 通過傳入一個存放特徵UDID的數組進去,過濾掉一些不要的特徵
[peripheral discoverCharacteristics:@[@"435", @"6456"] forService:service];
}
}
}
//查找到特徵的時候調用
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
// 遍歷所有的特徵
for (CBCharacteristic *characteristic in service.characteristics) {
// 過濾掉不想要的特徵
if ([characteristic.UUID isEqual:@"456"]) {
// 找到想要的特徵
self.dataInteractCharacteristic = characteristic;
} else if ([characteristic.UUID isEqual:@"789"]) {
self.peripheralInfoCharacteristic = characteristic;
}
}
}
@end
補充:藍牙現狀