博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通讯录 、 传感器
阅读量:5014 次
发布时间:2019-06-12

本文共 21887 字,大约阅读时间需要 72 分钟。

1 系统通讯录

1.1 问题

移动设备提供了一个很重要的的内置数据库——通讯录,通讯录放在SQLite3数据库中,但是应用之间不能直接访问,也就是其他的应用不能采用持久化技术直接访问通讯录数据库,为了实现通讯录数据库的访问,苹果开放了一些专门的API,在开发访问通讯录的应用中通常使用两个框架:AddressBook和AddressBookUI。本案例使用AddressBook框架和AddressBookUI框架实现对系统通讯录联系人的访问和编辑,如图-1所示:

图-1

1.2 方案

首先创建一个SingleViewApplication应用,在Storyboard文件中搭建选取联系人的界面,本案例中的场景是一个带有导航的TableViewController和ViewController进行绑定,标题设置为My Friend。

然后分别给左右两边拖放一个BarButtonItem控件,关联成ViewController的动作方法selectContacts:和newClick:,左边按钮的动作方法用于实现访问系统通讯录选择联系人,右边按钮的动作方法用于创建新联系人。

界面完成后在ViewController中定义两个属性NSMutableArray类型的属性contactNames和contactIDs,分别用于记录当前界面需要展示的联系人姓名和联系人ID,然后实现表视图的数据源方法,展示My Friend界面的联系人姓名。

然后实现selectContacts:方法,当点击左上角按钮时创建ABPeoplePickerNavigationController视图控制器对象peoplePicker,访问系统通讯录的联系人,并设置peoplePicker的委托对象。

实现ABPeoplePickerNavigationControllerDelegate协议中的方法peoplePickerNavigationController:didSelectPerson:,该方法会在选择完联系人时调用,因此该方法需要获取到所选联系人的姓名和ID,并将选中的联系人姓名展示在My Friend界面中。

接下来需要实现当用户点击My Friend界面的联系人姓名时,则展示该联系人的详细信息,因此需要在tableView:didSelectRowAtIndexPath:方法中创建ABPersonViewController视图控制器对象personViewController,并设置委托对象,然后展示出来。

ABPersonViewControllerDelegate有一个必须实现的方法personViewController:shouldPerformDefaultActionForPerson:property:该方法在选择联系人属性时被调用,返回YES则调用该属性的默认动作,返回NO则不做任何动作。

最后实现新建联系人方法newClick:,该方法中需要创建ABNewPersonViewController视图控制器对象newPersonViewController,用于展示新建联系人界面,并设置委托对象。ABNewPersonViewControllerDelegate协议有一个必须实现的方法newPersonViewController:didCompleteWithNewPerson:,该方法在联系人新建完成之后调用,本案例需要在该方法将联系人的联系人的姓名和ID记录下来,并将选中的联系人姓名展示在My Friend界面中。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:搭建界面

首先创建一个SingleViewApplication应用,在Storyboard文件中搭建选取联系人的界面,本案例中的场景是一个带有导航的TableViewController和ViewController进行绑定,标题设置为My Friend。

然后分别给左右两边拖放一个BarButtonItem控件,关联成ViewController的动作方法selectContacts:和newClick:,左边按钮的动作方法用于实现访问系统通讯录选择联系人,右边按钮的动作方法用于创建新联系人。

在Storyboard中完成的界面如图-2所示:

图-2

步骤二:选择联系人

界面完成后在ViewController中定义两个属性NSMutableArray类型的属性contactNames和contactIDs,分别用于记录当前界面需要展示的联系人姓名和联系人ID,并使用延迟加载方式初始化这两个属性,代码如下所示:

@interface ViewController ()//保存联系人姓名数组属性@property(nonatomic, strong) NSMutableArray *contactNames;//保存联系人ID数组属性@property(nonatomic, strong) NSMutableArray *contactIDs;@end//初始化-(NSMutableArray *)contactIDs {if (!_contactIDs) {_contactIDs = [@[]mutableCopy];}return _contactIDs;}-(NSMutableArray *)contactNames {if (!_contactNames) {_contactNames = [@[]mutableCopy];}return _contactNames;}然后实现表视图的数据源方法,展示My Friend界面的联系人姓名,代码如下所示: - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return self.contactNames.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {static NSString *CellIdentifier = @"Cell";UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];if (cell == nil) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];}cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;cell.textLabel.text = [self.contactNames objectAtIndex:[indexPath row]];return cell;}

 

接下来实现通过系统通讯录选择联系人的方法selectContacts:,当点击左上角按钮时创建ABPeoplePickerNavigationController视图控制器对象peoplePicker,访问系统通讯录的联系人,并设置peoplePicker的委托对象,代码如下所示:

  1. //选择联系人
  2. - (IBAction)selectContacts:(id)sender
  3. {
  4. //创建ABPeoplePickerNavigationController控制器,用于访问通讯录显示联系人列表
  5. ABPeoplePickerNavigationController *peoplePicker = [[ABPeoplePickerNavigationController alloc] init];
  6. peoplePicker.peoplePickerDelegate = self;
  7. [self presentViewController:peoplePicker animated:YES completion:nil];
  8. }

最后需要实现ABPeoplePickerNavigationControllerDelegate协议中的方法peoplePickerNavigationController:didSelectPerson:,该方法会在选择完联系人时调用,因此该方法需要获取到所选联系人的姓名和ID,并将选中的联系人姓名展示在My Friend界面中,代码如下所示:

 
  1. //选择联系人时调用
  2. - (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person {
  3. //获取选择联系人的姓名
  4. NSString *name = CFBridgingRelease(ABRecordCopyCompositeName(person));
  5. //将姓名添加到self.contactNames数组
  6. [self.contactNames addObject:name];
  7. //获取ID,将ID添加到self.contactIDs数组
  8. [self.contactIDs addObject:[NSNumber numberWithInt:ABRecordGetRecordID(person)]];
  9. //peoplePicker界面退回
  10. [peoplePicker dismissViewControllerAnimated:YES completion:nil];
  11. //取得最后一个放入contactIDs中的ID,也就是刚刚选择的ID
  12. NSIndexPath *path = [NSIndexPath indexPathForRow:self.contactIDs.count-1 inSection:0];
  13. //选中联系人插入到首页表视图中
  14. NSArray *arry = [NSArray arrayWithObject:path];
  15. [self.tableView insertRowsAtIndexPaths:arry withRowAnimation:UITableViewRowAnimationRight];
  16. }

当点击Cancel按钮时系统通讯录的联系人界面退出,代码如下所示:

 
  1. //点击Cancel按钮时调用
  2. - (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
  3. {
  4. [peoplePicker dismissViewControllerAnimated:YES completion:nil];
  5. }

完成效果如图-3,图-4所示:

图-3

图-4

步骤三:显示联系人详细信息当用户点击My Friend界面的联系人姓名时,则展示该联系人的详细信息,因此需要在tableView:didSelectRowAtIndexPath:方法中创建ABPersonViewController视图控制器对象personViewController,并设置委托对象然后展示出来,注意如果需要对联系人进行编辑需要将allowsEditing属性设置为YES,左上角才会出现编辑按钮否则不能进行编辑,代码如下所示: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {CFErrorRef error = NULL;//创建addressBook对象ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);//通过ID得到记录对象ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, [[self.contactIDs objectAtIndex:indexPath.row] intValue]);//创建ABPersonViewController控制器,用于显示和编辑联系人详细信息ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];//设置委托对象personViewController.personViewDelegate = self;//设定要显示的联系人对象personViewController.displayedPerson = person;//设定联系人视图是否可以编辑personViewController.allowsEditing = YES;//是否显示动作按钮personViewController.allowsActions = YES;//设置需要显示的属性,邮箱和电话personViewController.displayedProperties = @[[NSNumber numberWithInt:kABPersonEmailProperty],[NSNumber numberWithInt:kABPersonPhoneProperty]];[self.navigationController pushViewController:personViewController animated:YES];CFRelease(addressBook);}ABPersonViewControllerDelegate有一个必须实现的方法personViewController:shouldPerformDefaultActionForPerson:property:该方法在选择联系人属性时被调用,返回YES则调用该属性的默认动作,返回NO则不做任何动作,代码如下所示:- (BOOL)personViewController:(ABPersonViewController *)personViewControllershouldPerformDefaultActionForPerson:(ABRecordRef)personproperty:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue{return YES;}

 

完成效果如图-5所示:

图-5

步骤四:新建联系人

实现新建联系人方法newClick:,该方法中需要创建ABNewPersonViewController视图控制器对象newPersonViewController,用于展示新建联系人界面,并设置委托对象,代码如下所示:- (IBAction)newClick:(id)sender {//创建ABNewPersonViewController控制器,用于新建联系人ABNewPersonViewController *newPersonViewController = [[ABNewPersonViewController alloc] init];//设置委托对象newPersonViewController.newPersonViewDelegate = self;UINavigationController *newNavigationController = [[UINavigationController alloc]initWithRootViewController:newPersonViewController];[self presentViewController:newNavigationController animated:YES completion:nil];}ABNewPersonViewControllerDelegate协议有一个必须实现的方法newPersonViewController:didCompleteWithNewPerson:,该方法在联系人新建完成之后调用,本案例需要在该方法将联系人的联系人的姓名和ID记录下来,并将选中的联系人姓名展示在My Friend界面中,代码如下所示: - (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewdidCompleteWithNewPerson:(ABRecordRef)person{NSString *name = CFBridgingRelease(ABRecordCopyCompositeName(person));[self.contactNames addObject:name];[self.contactIDs addObject:[NSNumber numberWithInt:ABRecordGetRecordID(person)]];[newPersonView dismissViewControllerAnimated:YES completion:nil];//取得最后一个放入contactIDs中的ID,也就是刚刚选择的IDNSIndexPath *path = [NSIndexPath indexPathForRow:self.contactIDs.count-1 inSection:0];//选中联系人插入到首页表视图中NSArray *arry = [NSArray arrayWithObject:path];[self.tableView insertRowsAtIndexPaths:arry withRowAnimation:UITableViewRowAnimationRight];}

 

新建的联系人会被添加到系统通讯录中,效果如图-6,图-7所示:

图-6

图-7

1.4 完整代码

 
本案例中,TRViewController.m文件中的完整代码如下所示: #import "ViewController.h"#import 
#import
@interface ViewController ()
//保存联系人姓名数组属性@property(nonatomic, strong) NSMutableArray *contactNames;//保存联系人ID数组属性@property(nonatomic, strong) NSMutableArray *contactIDs;@end@implementation ViewController-(NSMutableArray *)contactIDs {if (!_contactIDs) {_contactIDs = [@[]mutableCopy];}return _contactIDs;}-(NSMutableArray *)contactNames {if (!_contactNames) {_contactNames = [@[]mutableCopy];}return _contactNames;}#pragma mark -#pragma mark 表视图数据源- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return self.contactNames.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {static NSString *CellIdentifier = @"Cell";UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];if (cell == nil) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];}cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;cell.textLabel.text = [self.contactNames objectAtIndex:[indexPath row]];return cell;}- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {CFErrorRef error = NULL;//创建addressBook对象ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);//通过ID得到记录对象ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, [[self.contactIDs objectAtIndex:indexPath.row] intValue]);//创建ABPersonViewController控制器,用于显示和编辑联系人详细信息ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];//设置委托对象personViewController.personViewDelegate = self;//设定要显示的联系人对象personViewController.displayedPerson = person;//设定联系人视图是否可以编辑personViewController.allowsEditing = YES;//是否显示动作按钮personViewController.allowsActions = YES;//设置需要显示的属性,邮箱和电话personViewController.displayedProperties = @[[NSNumber numberWithInt:kABPersonEmailProperty],[NSNumber numberWithInt:kABPersonPhoneProperty]];[self.navigationController pushViewController:personViewController animated:YES];CFRelease(addressBook);}//新建联系人- (IBAction)newClick:(id)sender {//创建ABNewPersonViewController控制器,用于新建联系人ABNewPersonViewController *newPersonViewController = [[ABNewPersonViewController alloc] init];//设置委托对象newPersonViewController.newPersonViewDelegate = self;UINavigationController *newNavigationController = [[UINavigationController alloc]initWithRootViewController:newPersonViewController];[self presentViewController:newNavigationController animated:YES completion:nil];}//选择联系人- (IBAction)selectContacts:(id)sender{//创建ABPeoplePickerNavigationController控制器,用于访问通讯录显示联系人列表ABPeoplePickerNavigationController *peoplePicker = [[ABPeoplePickerNavigationController alloc] init];peoplePicker.peoplePickerDelegate = self;[self presentViewController:peoplePicker animated:YES completion:nil];}#pragma mark -#pragma mark ABPeoplePickerNavigationController 委托方法实现//点击Cancel按钮时调用- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{[peoplePicker dismissViewControllerAnimated:YES completion:nil];}//选择联系人时调用- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person {//获取选择联系人的姓名NSString *name = CFBridgingRelease(ABRecordCopyCompositeName(person));//将姓名添加到self.contactNames数组[self.contactNames addObject:name];//获取ID,将ID添加到self.contactIDs数组[self.contactIDs addObject:[NSNumber numberWithInt:ABRecordGetRecordID(person)]];//peoplePicker界面退回[peoplePicker dismissViewControllerAnimated:YES completion:nil];//取得最后一个放入contactIDs中的ID,也就是刚刚选择的IDNSIndexPath *path = [NSIndexPath indexPathForRow:self.contactIDs.count-1 inSection:0];//选中联系人插入到首页表视图中NSArray *arry = [NSArray arrayWithObject:path];[self.tableView insertRowsAtIndexPaths:arry withRowAnimation:UITableViewRowAnimationRight];}#pragma mark -#pragma mark ABPersonViewController 委托方法实现- (BOOL)personViewController:(ABPersonViewController *)personViewControllershouldPerformDefaultActionForPerson:(ABRecordRef)personproperty:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue{return YES;}#pragma mark -#pragma mark ABNewPersonViewController 委托方法实现- (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewdidCompleteWithNewPerson:(ABRecordRef)person{NSString *name = CFBridgingRelease(ABRecordCopyCompositeName(person));[self.contactNames addObject:name];[self.contactIDs addObject:[NSNumber numberWithInt:ABRecordGetRecordID(person)]];[newPersonView dismissViewControllerAnimated:YES completion:nil];//取得最后一个放入contactIDs中的ID,也就是刚刚选择的IDNSIndexPath *path = [NSIndexPath indexPathForRow:self.contactIDs.count-1 inSection:0];//选中联系人插入到首页表视图中NSArray *arry = [NSArray arrayWithObject:path];[self.tableView insertRowsAtIndexPaths:arry withRowAnimation:UITableViewRowAnimationRight];}@end
 

2 平衡球

2.1 问题

IOS可以通过内置的加速计知道用户握持设备的方式,以及用户是否移动了设备,Core Motion框架提供设备移动的所有值。本案例使用Core Motion框架完成一个平衡球的小游戏,用户移动设备小球会根据用户移动的方向滚动,用户保持小球滚动到终点而不碰撞到墙壁,如图-8所示:

图-8

2.2 方案

首先创建一个SingleViewApplication应用,在Storyboard文件中搭建界面,本案例中的场景中使用带有背景颜色的ImageView控件当做隔墙,然后左上角摆放一个小球,同样是ImageView控件。将所有隔墙关联成ViewController的IBOutletCollection属性walls,将小球关联成ViewController的IBOutlet属性ball。

其次在ViewController类扩展中定义两个私有属性CMMotionManager类型的motionManager和NSOperationQueue类型的queue。在viewDidLoad方法中对这两个属性进行初始化,motionManager将观察动作事件,它需要创建一个队列用做完成工作的容器。

接下来配置加速器,首先确保设备确实拥有加速器,然后设置更新频率为1/15s,最后使用startAccelerometerUpdatesToQueue:withHandler:方法告诉motionManager开始报告加速计更新,传入队列和代码块,队列中放置着每次发生更新时要完成的工作,代码块定义这些工作。

最后完成代码块中的代码,本案例中代码块中需要根据每次更新的数据计算出小球滚动的距离和方向,并且需要判断小球是否碰到墙壁,碰到墙壁则游戏结束重新开始,未碰撞到任何墙壁顺利到达终点则游戏成功。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:搭建界面

首先创建一个SingleViewApplication应用,在Storyboard文件中搭建界面,本案例中的场景中使用带有背景颜色的ImageView控件当做隔墙,然后左上角摆放一个小球,同样是ImageView控件。将所有隔墙关联成ViewController的IBOutletCollection属性walls,将小球关联成ViewController的IBOutlet属性ball,代码如下所示:

@interface ViewController ()//终点位置@property (weak, nonatomic) IBOutlet UIImageView *green;@property (weak, nonatomic) IBOutlet UIImageView *red;@property (strong, nonatomic) IBOutletCollection(UIImageView) NSArray *walls;@property (weak, nonatomic) IBOutlet UIButton *ball;@end

 

在Storyboard中完成的界面如图-9所示:

图-9

步骤二:创建动作管理器

在ViewController类扩展中定义两个私有属性CMMotionManager类型的motionManager和NSOperationQueue类型的queue。在viewDidLoad方法中对这两个属性进行初始化,motionManager将观察动作事件,它需要创建一个队列用做完成工作的容器,代码如下所示:@property (nonatomic,strong) CMMotionManager *motionManager;@property (nonatomic,strong) NSOperationQueue *queue;接下来配置加速器,首先确保设备确实拥有加速器,然后设置更新频率为1/15s,最后使用startAccelerometerUpdatesToQueue:withHandler:方法告诉motionManager开始报告加速计更新,传入队列和代码块,队列中放置着每次发生更新时要完成的工作,代码块定义这些工作,代码如下所示:- (void)viewDidLoad {[super viewDidLoad];self.motionManager = [[CMMotionManager alloc]init];self.queue = [[NSOperationQueue alloc]init];if (self.motionManager.accelerometerAvailable) {self.motionManager.accelerometerUpdateInterval = 1.0/15;[self.motionManager startAccelerometerUpdatesToQueue:self.queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {}];     }}步骤三:实现小球滚动功能在代码块中实现小球滚动功能,需要根据每次更新的accelerometerData.acceleration数据计算出小球滚动的距离和方向,然后回到主线程更新界面,需要判断小球是否碰到墙壁,碰到墙壁则游戏结束重新开始,未碰撞到任何墙壁顺利到达终点则游戏成功,代码如下所示: - (void)viewDidLoad {[super viewDidLoad];self.motionManager = [[CMMotionManager alloc]init];self.queue = [[NSOperationQueue alloc]init];if (self.motionManager.accelerometerAvailable) {self.motionManager.accelerometerUpdateInterval = 1.0/15;// [self.motionManager startAccelerometerUpdates];[self.motionManager startAccelerometerUpdatesToQueue:self.queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {//计算小球滚动的距离float x = oldx+.2*accelerometerData.acceleration.x;float y = oldy+.2*accelerometerData.acceleration.y;NSLog(@"%f,%f",accelerometerData.acceleration.x,accelerometerData.acceleration.y);NSArray *array = @[@(x),@(y)];//回到主线程更新界面[self performSelectorOnMainThread:@selector(moveBall:) withObject:array waitUntilDone:NO];}];}//记录小球最开始的中心点,游戏重新开始将回到该位置p = self.ball.center;//屏幕尺寸scrennSize = [UIScreen mainScreen].bounds.size;}-(void)moveBall:(NSArray*)array {float x = [array[0] floatValue];float y = [array[1] floatValue];self.ball.center = CGPointMake(self.ball.center.x+x,self.ball.center.y-y);oldx = x;oldy = y;//判断小球是否碰撞到屏幕两边需要改变方向if (self.ball.frame.origin.x<=0) {self.ball.frame = CGRectMake(0, self.ball.frame.origin.y, self.ball.frame.size.width, self.ball.frame.size.height);oldx = -oldx*.1;}else if (self.ball.frame.origin.x>=(scrennSize.width-self.ball.frame.size.width)) {self.ball.frame = CGRectMake((scrennSize.width-self.ball.frame.size.width), self.ball.frame.origin.y, self.ball.frame.size.width, self.ball.frame.size.height);oldx = -oldx*.1;}if (self.ball.frame.origin.y<=0) {self.ball.frame = CGRectMake(self.ball.frame.origin.x, 0, self.ball.frame.size.width, self.ball.frame.size.height);oldy = -oldy*.1;}else if (self.ball.frame.origin.y>=(scrennSize.height-self.ball.frame.size.height)) {self.ball.frame = CGRectMake(self.ball.frame.origin.x,(scrennSize.height-self.ball.frame.size.height), self.ball.frame.size.width, self.ball.frame.size.height);oldy = -oldy*.1;}//判断是否与墙壁有碰撞for (UIImageView *wall in self.walls) {if (CGRectIntersectsRect(self.ball.frame, wall.frame)) {UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"提示" message:@"Game Over" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:@"重新开始", nil];[av show];self.ball.center = p;return;}}if (CGRectIntersectsRect(self.ball.frame, self.green.frame)) {UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"提示" message:@"Successful" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:@"重新开始", nil];[av show];return;}else if (CGRectIntersectsRect(self.ball.frame, self.red.frame)) {UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"提示" message:@"fair" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:@"重新开始", nil];[av show];return;}}-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {if (buttonIndex==1) {self.ball.center = p;}}最后不要忘记放置手机屏幕旋转和隐藏状态栏,代码如下所示:-(NSUInteger)supportedInterfaceOrientations {r%turn UIInterfaceOrientationMaskPortrait;}-(BOOL)prdfersStatuSBarHidden { return YES;}

 

完成效果如图-10,图-11所示:

图 10

图-11

2.4 完整代码

本案例中,ViewController.m文件中的完整代码如下所示:#import "ViewController.h"#import 
@interface ViewController (){ CGPoint p; float oldx; float oldy; CGSize scrennSize;}@property (nonatomic,strong) CMMotionManager *motionManager;@property (nonatomic,strong) NSOperationQueue *queue;@property (weak, nonatomic) IBOutlet UIImageView *green;@property (weak, nonatomic) IBOutlet UIImageView *red;@property (strong, nonatomic) IBOutletCollection(UIImageView) NSArray *walls;@property (weak, nonatomic) IBOutlet UIButton *ball;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; self.motionManager = [[CMMotionManager alloc]init]; self.queue = [[NSOperationQueue alloc]init]; if (self.motionManager.accelerometerAvailable) { self.motionManager.accelerometerUpdateInterval = 1.0/15; // [self.motionManager startAccelerometerUpdates]; [self.motionManager startAccelerometerUpdatesToQueue:self.queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { //计算小球滚动的距离 float x = oldx+.2*accelerometerData.acceleration.x; float y = oldy+.2*accelerometerData.acceleration.y; NSLog(@"%f,%f",accelerometerData.acceleration.x,accelerometerData.acceleration.y); NSArray *array = @[@(x),@(y)]; //回到主线程更新界面 [self performSelectorOnMainThread:@selector(moveBall:) withObject:array waitUntilDone:NO]; }]; } //记录小球最开始的中心点,游戏重新开始将回到该位置 p = self.ball.center; //屏幕尺寸 scrennSize = [UIScreen mainScreen].bounds.size;}-(void)moveBall:(NSArray*)array { float x = [array[0] floatValue]; float y = [array[1] floatValue]; self.ball.center = CGPointMake(self.ball.center.x+x,self.ball.center.y-y); oldx = x; oldy = y; //判断小球是否碰撞到屏幕两边需要改变方向 if (self.ball.frame.origin.x<=0) { self.ball.frame = CGRectMake(0, self.ball.frame.origin.y, self.ball.frame.size.width, self.ball.frame.size.height); oldx = -oldx*.1; }else if (self.ball.frame.origin.x>=(scrennSize.width-self.ball.frame.size.width)) { self.ball.frame = CGRectMake((scrennSize.width-self.ball.frame.size.width), self.ball.frame.origin.y, self.ball.frame.size.width, self.ball.frame.size.height); oldx = -oldx*.1; } if (self.ball.frame.origin.y<=0) { self.ball.frame = CGRectMake(self.ball.frame.origin.x, 0, self.ball.frame.size.width, self.ball.frame.size.height); oldy = -oldy*.1; }else if (self.ball.frame.origin.y>=(scrennSize.height-self.ball.frame.size.height)) { self.ball.frame = CGRectMake(self.ball.frame.origin.x,(scrennSize.height-self.ball.frame.size.height), self.ball.frame.size.width, self.ball.frame.size.height); oldy = -oldy*.1; } //判断是否与墙壁有碰撞 for (UIImageView *wall in self.walls) { if (CGRectIntersectsRect(self.ball.frame, wall.frame)) { UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"提示" message:@"Game Over" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:@"重新开始", nil]; [av show]; self.ball.center = p; return; } } if (CGRectIntersectsRect(self.ball.frame, self.green.frame)) { UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"提示" message:@"Successful" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:@"重新开始", nil]; [av show]; return; }else if (CGRectIntersectsRect(self.ball.frame, self.red.frame)) { UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"提示" message:@"fair" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:@"重新开始", nil]; [av show]; return; }}-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex==1) { self.ball.center = p; }}-(NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait;}-(BOOL)prefersStatusBarHidden { return YES;}@end

 

转载于:https://www.cnblogs.com/52190112cn/p/5052137.html

你可能感兴趣的文章
转载,gini系数代码对应的公式
查看>>
编译安装mysql-5.6.40
查看>>
年终总结
查看>>
初创互联网公司技术架构变迁之路
查看>>
【BZOJ 3676】 3676: [Apio2014]回文串 (SAM+Manacher+倍增)
查看>>
【网络流24题】No. 13 星际转移问题 (网络判定 最大流)
查看>>
解析$.grep()源码及透过$.grep()看(两次取反)!!的作用
查看>>
[模板] 字符串hash
查看>>
SGU438_The Glorious Karlutka River =)
查看>>
Linux集群及LVS简介
查看>>
简单几何(直线与圆的交点) ZOJ Collision 3728
查看>>
Codeforces Round #327 (Div. 2)
查看>>
如何解决Provisional headers are shown问题(转)
查看>>
开发网站遇到的bug
查看>>
实现简单的接口自动化测试平台
查看>>
EXCEL工作表合并
查看>>
Prime Path
查看>>
ODAC(V9.5.15) 学习笔记(三)TOraSession(2)
查看>>
单纯形法
查看>>
SQL中的replace函数
查看>>