一、网络通信
1. 获取服务器数据
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
mgr.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"application/json",nil];
//拼接请求参数
NSDictionary *parameter = @{@"user" : @"user",
@"title" : @"title",
@"description" : @"description",
@"panorama" : @"panorama",
@"filesize" : @"filesize",
@"width" : @"width",
@"thumbnail" : @"thumbnail",
@"likes" : @"likes",
@"collections" : @"collections",
@"created" : @"created"
};
// 取出最前面的微博(最新的微博,ID最大的微博)
HWStatusFrame *firstStatusF = [self.statusFrames firstObject];
[mgr GET:@"http://114.214.164.105:8000/api/panoramas/" parameters:parameter success:^(AFHTTPRequestOperation *operation, id responseObject) {
//获取相应用户的微博微博字典数组,由于服务器上的是最新发出的排在最后和我们这个微博要求相反,所以要倒过来拿
NSArray *reverseArray = [[responseObject reverseObjectEnumerator] allObjects];
//李明杰mj的框架
/*
MJExtension是一套字典和模型之间互相转换的超轻量级框架
MJExtension能完成的功能
字典(JSON) --> 模型(Model)
模型(Model) --> 字典(JSON)
字典数组(JSON Array) --> 模型数组(Model Array)
模型数组(Model Array) --> 字典数组(JSON Array)
*/
//这里将字典数组转成模型数组
/*
如何从plist中读取字典,并转换成对象模型
http://www.cnblogs.com/fxiaoquan/archive/2015/04/18/4438126.html
下面的直接利用第三份开源框架字典转模型工具
*/
NSArray *newStatuses = [HWStatus mj_objectArrayWithKeyValuesArray:reverseArray];
//将HWStatus数组转换成HWstatusFrame数组
NSMutableArray *Frames = [NSMutableArray array];
//这个newFrames包含所有数据,所以要加上判断
for(HWStatus *status in newStatuses)
{
if(status.created > firstStatusF.status.created)
{
HWStatusFrame *f = [[HWStatusFrame alloc] init];
f.status = status;
[Frames addObject:f];
}
else
break;
}
[self.statusFrames addObjectsFromArray:Frames];
//可以获取数据
//NSLog(@"%@",reverseArray);
//刷新表格
[self.tableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error == %@",error);
}];
//点击全景图片进行展示,此处用原图
#pragma mark - 代理方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//获取的全部内容的key
HWStatusCell *cell = [HWStatusCell cellWithTableView:tableView];
//statusFrames所有数据模型的集合
cell.statusFrame = self.statusFrames[indexPath.row];
//拼url
NSString *panoString = [NSString stringWithFormat:@"http://114.214.164.105:8000%@",cell.statusFrame.status.panorama];
PanoViewController *panoView = [[PanoViewController alloc] init];
panoView.urlString = panoString;
NSString *biaoti = [NSString stringWithFormat:@"%@",cell.statusFrame.status.title];
panoView.title = biaoti;
// 当test1控制器被push的时候,test1所在的tabbarcontroller的tabbar会自动隐藏
// 当test1控制器被pop的时候,test1所在的tabbarcontroller的tabbar会自动显示
// test1.hidesBottomBarWhenPushed = YES;
// self.navigationController === HWNavigationController
//push进来的会被拦截
[self.navigationController pushViewController:panoView animated:YES];
//[self presentViewController:panoView animated:YES completion:nil];
}
3. 上传数据
AFHTTPRequestOperationManager *mgr= [AFHTTPRequestOperationManager manager];
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"user"] = @"1";
params[@"description"] = @"Panoramic Picture";
params[@"title"] = self.textView.text;
[mgr POST:@"http://114.214.164.105:8000/api/panoramas/" parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
UIImage *image = [self.photosView.photos firstObject];
NSData *data = UIImageJPEGRepresentation(image, 1.0);
[formData appendPartWithFileData:data name:@"panorama" fileName:@"PIC" mimeType:@"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
[MBProgressHUD showSuccess:@"发送成功"];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[MBProgressHUD showSuccess:@"发送失败"];
NSLog(@"%@", self.textView.text);
NSLog(@"%@", error.localizedDescription);
NSLog(@"%@", error.localizedFailureReason);
NSLog(@"%@", error.userInfo);
}];
二、手写代码而非拖控件需要做的事
下列函数都在AppDelegate中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// 1.创建窗口
self.window = [[UIWindow alloc] init];
self.window.frame = [UIScreen mainScreen].bounds;
// 2.设置根控制器
NSString *key = @"CFBundleVersion";
// 上一次的使用版本(存储在沙盒中的版本号)
NSString *lastVersion = [[NSUserDefaults standardUserDefaults] objectForKey:key];
// 当前软件的版本号(从Info.plist中获得)
NSString *currentVersion = [NSBundle mainBundle].infoDictionary[key];
if ([currentVersion isEqualToString:lastVersion]) { // 版本号相同:这次打开和上次打开的是同一个版本
self.window.rootViewController = [[loginViewController alloc] init];
} else { // 这次打开的版本和上一次不一样,显示新特性
self.window.rootViewController = [[HWNewfeatureViewController alloc] init];
// 将当前的版本号存进沙盒
[[NSUserDefaults standardUserDefaults] setObject:currentVersion forKey:key];
[[NSUserDefaults standardUserDefaults] synchronize];//内存数据立即传入沙盒
}
// 3.显示窗口
[self.window makeKeyAndVisible];
return YES;
}
- (void) applicationDidReceiveMemoryWarning:(UIApplication *)application
{
SDWebImageManager *mgr = [SDWebImageManager sharedManager];
//取消下载
[mgr cancelAll];
[mgr.imageCache clearMemory];
}
三、自定义cell
//从可复用的队列里拿出来
+ (instancetype)cellWithTableView:(UITableView *)tableView
{
static NSString *ID = @"status";
//一个表视图维护着一个可复用单元的队列或者列表。当要显示一个新的单元的时候就调用这个方法,这个方法会出列一个已经存在的单元。
HWStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[HWStatusCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
return cell;
}
//定义每个cell的样式
- (id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self)
{
//体框架
UIView *originalView = [[UIView alloc] init];
[self.contentView addSubview:originalView];
self.originalView = originalView;
//头像
UIImageView *iconView = [[UIImageView alloc] init];
[originalView addSubview:iconView];
self.iconView = iconView;
//配图
UIImageView *photoView = [[UIImageView alloc] init];
[originalView addSubview:photoView];
self.photoView = photoView;
//昵称
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.font = HWStatusCellNameFont;
[originalView addSubview:nameLabel];
self.nameLabel = nameLabel;
//时间
UILabel *timeLabel = [[UILabel alloc] init];
timeLabel.font = HWStatusCellTimeFont;
[originalView addSubview:timeLabel];
self.timeLabel = timeLabel;
//正文
UILabel *contentLabel =[[UILabel alloc] init];
contentLabel.font = HWContentCellContentFont;
[originalView addSubview:contentLabel];
self.contentLabel = contentLabel;
}
return self;
}
NSData *iconData = [user objectForKey:@"icon"];
//对象归档,二进制数据转换为响应格式
UIImage *icon = [NSKeyedUnarchiver unarchiveObjectWithData:iconData];
//拼url
NSString *urlString = [NSString stringWithFormat:@"http://114.214.164.105:8000%@",status.thumbnail];
[self.photoView sd_setImageWithURL:[NSURL URLWithString:urlString] placeholderImage:nil];
self.photoView.backgroundColor = [UIColor orangeColor];
四、系统框架的搭建
1.NavigationController的设置
+ (void)initialize
{
// 设置整个项目所有item的主题样式
UIBarButtonItem *item = [UIBarButtonItem appearance];
// 设置普通状态
// key:NS****AttributeName
NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
textAttrs[NSForegroundColorAttributeName] = [UIColor orangeColor];
textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:15];
[item setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
// 设置不可用状态,不好使颜色
NSMutableDictionary *disableTextAttrs = [NSMutableDictionary dictionary];
disableTextAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:0.7];
disableTextAttrs[NSFontAttributeName] = textAttrs[NSFontAttributeName];
[item setTitleTextAttributes:disableTextAttrs forState:UIControlStateDisabled];
}
/**
* 重写这个方法目的:能够拦截所有push进来的控制器
*
* @param viewController 即将push进来的控制器
*/
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (self.viewControllers.count > 0) { // 这时push进来的控制器viewController,不是第一个子控制器(不是根控制器)
/* 自动显示和隐藏tabbar */
viewController.hidesBottomBarWhenPushed = YES;
/* 设置导航栏上面的内容 */
// 设置左边的返回按钮
viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(back) image:@"navigationbar_back" highImage:@"navigationbar_back_highlighted"];
// 设置右边的更多按钮
viewController.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(more) image:@"navigationbar_more" highImage:@"navigationbar_more_highlighted"];
}
[super pushViewController:viewController animated:animated];
}
- (void)back
{
#warning 这里要用self,不是self.navigationController
// 因为self本来就是一个导航控制器,self.navigationController这里是nil的
[self popViewControllerAnimated:YES];
}
2.系统整体架构是一个TabBar
- (void)viewDidLoad
{
[super viewDidLoad];
// 1.初始化子控制器
HWHomeViewController *home = [[HWHomeViewController alloc] init];
[self addChildVc:home title:@"首页" image:@"tabbar_home" selectedImage:@"tabbar_home_selected"];
HWMessageCenterViewController *messageCenter = [[HWMessageCenterViewController alloc] init];
[self addChildVc:messageCenter title:@"消息" image:@"tabbar_message_center" selectedImage:@"tabbar_message_center_selected"];
HWDiscoverViewController *discover = [[HWDiscoverViewController alloc] init];
[self addChildVc:discover title:@"发现" image:@"tabbar_discover" selectedImage:@"tabbar_discover_selected"];
HWProfileViewController *profile = [[HWProfileViewController alloc] init];
[self addChildVc:profile title:@"我" image:@"tabbar_profile" selectedImage:@"tabbar_profile_selected"];
// 2.更换系统自带的tabbar
HWTabBar *tabBar = [[HWTabBar alloc] init];
[self setValue:tabBar forKeyPath:@"tabBar"];
/*
[self setValue:tabBar forKeyPath:@"tabBar"];相当于self.tabBar = tabBar;
[self setValue:tabBar forKeyPath:@"tabBar"];这行代码过后,tabBar的delegate就是HWTabBarViewController
说明,不用再设置tabBar.delegate = self;
*/
/*
1.如果tabBar设置完delegate后,再执行下面代码修改delegate,就会报错
tabBar.delegate = self;
2.如果再次修改tabBar的delegate属性,就会报下面的错误
错误信息:Changing the delegate of a tab bar managed by a tab bar controller is not allowed.
错误意思:不允许修改TabBar的delegate属性(这个TabBar是被TabBarViewController所管理的)
*/
}
五、新特性界面
- (void)viewDidLoad
{
[super viewDidLoad];
// 1.创建一个scrollView:显示所有的新特性图片
UIScrollView *scrollView = [[UIScrollView alloc] init];
scrollView.frame = self.view.bounds;
[self.view addSubview:scrollView];
self.scrollView = scrollView;
// 2.添加图片到scrollView中
CGFloat scrollW = scrollView.width;
CGFloat scrollH = scrollView.height;
for (int i = 0; i<HWNewfeatureCount; i++) {
UIImageView *imageView = [[UIImageView alloc] init];
imageView.width = scrollW;
imageView.height = scrollH;
imageView.y = 0;
imageView.x = i * scrollW;
// 显示图片
NSString *name = [NSString stringWithFormat:@"new_feature_%d", i + 1];
imageView.image = [UIImage imageNamed:name];
[scrollView addSubview:imageView];
// 如果是最后一个imageView,就往里面添加其他内容
if (i == HWNewfeatureCount - 1) {
[self setupLastImageView:imageView];
}
}
#warning 默认情况下,scrollView一创建出来,它里面可能就存在一些子控件了
#warning 就算不主动添加子控件到scrollView中,scrollView内部还是可能会有一些子控件
// 3.设置scrollView的其他属性
// 如果想要某个方向上不能滚动,那么这个方向对应的尺寸数值传0即可
scrollView.contentSize = CGSizeMake(HWNewfeatureCount * scrollW, 0);
scrollView.bounces = NO; // 去除弹簧效果
scrollView.pagingEnabled = YES;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.delegate = self;
// 4.添加pageControl:分页,展示目前看的是第几页
UIPageControl *pageControl = [[UIPageControl alloc] init];
pageControl.numberOfPages = HWNewfeatureCount;
pageControl.backgroundColor = [UIColor redColor];
pageControl.currentPageIndicatorTintColor = HWColor(253, 98, 42);
pageControl.pageIndicatorTintColor = HWColor(189, 189, 189);
pageControl.centerX = scrollW * 0.5;
pageControl.centerY = scrollH - 50;
[self.view addSubview:pageControl];
self.pageControl = pageControl;
// UIPageControl就算没有设置尺寸,里面的内容还是照常显示的
// pageControl.width = 100;
// pageControl.height = 50;
// pageControl.userInteractionEnabled = NO;
// UITextField *text = [[UITextField alloc] init];
// text.frame = CGRectMake(10, 20, 100, 50);
// text.borderStyle = UITextBorderStyleRoundedRect;
// [self.view addSubview:text];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
double page = scrollView.contentOffset.x / scrollView.width;
// 四舍五入计算出页码
self.pageControl.currentPage = (int)(page + 0.5);
}
/**
* 初始化最后一个imageView
*
* @param imageView 最后一个imageView
*/
- (void)setupLastImageView:(UIImageView *)imageView
{
// 开启交互功能
imageView.userInteractionEnabled = YES;
// 1.分享给大家(checkbox)
UIButton *shareBtn = [[UIButton alloc] init];
[shareBtn setImage:[UIImage imageNamed:@"new_feature_share_false"] forState:UIControlStateNormal];
[shareBtn setImage:[UIImage imageNamed:@"new_feature_share_true"] forState:UIControlStateSelected];
[shareBtn setTitle:@"分享给大家" forState:UIControlStateNormal];
[shareBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
shareBtn.titleLabel.font = [UIFont systemFontOfSize:15];
shareBtn.width = 200;
shareBtn.height = 30;
shareBtn.centerX = imageView.width * 0.5;
shareBtn.centerY = imageView.height * 0.65;
[shareBtn addTarget:self action:@selector(shareClick:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:shareBtn];
// shareBtn.backgroundColor = [UIColor redColor];
// shareBtn.imageView.backgroundColor = [UIColor blueColor];
// shareBtn.titleLabel.backgroundColor = [UIColor yellowColor];
// top left bottom right
// EdgeInsets: 自切
// contentEdgeInsets:会影响按钮内部的所有内容(里面的imageView和titleLabel)
// shareBtn.contentEdgeInsets = UIEdgeInsetsMake(10, 100, 0, 0);
// titleEdgeInsets:只影响按钮内部的titleLabel
shareBtn.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
// imageEdgeInsets:只影响按钮内部的imageView
// shareBtn.imageEdgeInsets = UIEdgeInsetsMake(20, 0, 0, 50);
// shareBtn.titleEdgeInsets
// shareBtn.imageEdgeInsets
// shareBtn.contentEdgeInsets
// 2.开始微博
UIButton *startBtn = [[UIButton alloc] init];
[startBtn setBackgroundImage:[UIImage imageNamed:@"new_feature_finish_button"] forState:UIControlStateNormal];
[startBtn setBackgroundImage:[UIImage imageNamed:@"new_feature_finish_button_highlighted"] forState:UIControlStateHighlighted];
startBtn.size = startBtn.currentBackgroundImage.size;
startBtn.centerX = shareBtn.centerX;
startBtn.centerY = imageView.height * 0.75;
[startBtn setTitle:@"开始微博" forState:UIControlStateNormal];
[startBtn addTarget:self action:@selector(startClick) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:startBtn];
}
六、全景图显示
- (void)viewDidLoad {
[super viewDidLoad];
plView = (PLView *) self.view;
plView.delegate = self;
//显示全景图片
[self showPanoView];
}
- (void)showPanoView
{
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:_urlString]];
NSURLResponse *response = nil;
NSError *error = nil;
//获取服务器端全景图片的二进制数据流
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
if([data length] > 0 && error == nil) {
UIImage *img = [UIImage imageWithData:data];//将数据流转成图片
/*************将4000*2000图片降到2048*1024************/
CGSize size = CGSizeMake(2048, 1024);
UIImage *newImage = [self imageWithImageSimple:img scaledToSize:size ];
//************************
//加入到故事板上,PLIPanorama是一个协议
NSObject<PLIPanorama> *panorama = nil;
//Spherical2 panorama example (supports up 2048x1024 texture)
//调用类方法,产生一个PLSpherical2Panorama类型的对象panorama
panorama = [PLSpherical2Panorama panorama];
//img into CGImage,是用来重绘图形的类,在应用时是按照图像的像素矩阵来绘制图片的,它们可以用来处理bitmap
CGImageRef cgimage = newImage.CGImage;
//将cgimage添加到panorama上
[(PLSpherical2Panorama *)panorama setImage:[PLImage imageWithCGImage:cgimage]];
//将panorama添加到plview上
[plView setPanorama:panorama];
//Add a hotspot
PLTexture *hotspotTexture = [PLTexture textureWithImage:[PLImage imageWithPath:[[NSBundle mainBundle] pathForResource:@"hotspot" ofType:@"png"]]];
PLHotspot *hotspot = [PLHotspot hotspotWithId:(kIdMin + random() % ((kIdMax + 1) - kIdMin)) texture:hotspotTexture atv:0.0f ath:0.0f width:0.08f height:0.08f];
[panorama addHotspot:hotspot];
NSLog(@"图片加载完毕");
}
else{
NSLog((@"error:%@",error));
}
}
//改变图片分辨率方法
- ( UIImage *)imageWithImageSimple:( UIImage *)image scaledToSize:( CGSize )newSize
{
// Create a graphics image context
UIGraphicsBeginImageContext (newSize);
// Tell the old image to draw in this new context, with the desired
// new size
[image drawInRect : CGRectMake ( 0 , 0 ,newSize. width ,newSize. height )];
// Get the new image from the context
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext ();
// End the context
UIGraphicsEndImageContext ();
// Return the new image.
return newImage;
}
七、引导式拍摄
1.自定义相机
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//初始化会话
self.captureSession=[[AVCaptureSession alloc]init];
if ([self.captureSession canSetSessionPreset:AVCaptureSessionPreset640x480]) {//设置分辨率
//self.captureSession.sessionPreset=AVAssetExportPresetLowQuality;
[self.captureSession setSessionPreset:AVCaptureSessionPreset640x480];
}
else
{
NSLog(@"不支持分辨率设置");
}
//获得输入设备
AVCaptureDevice *captureDevice=[self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];//取得后置摄像头
if (!captureDevice) {
NSLog(@"取得后置摄像头时出现问题.");
return;
}
NSError *error=nil;
//根据输入设备初始化设备输入对象,用于获得输入数据
_captureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:captureDevice error:&error];
if (error) {
NSLog(@"取得设备输入对象时出错,错误原因:%@",error.localizedDescription);
return;
}
//初始化设备输出对象,用于获得输出数据
_captureStillImageOutput=[[AVCaptureStillImageOutput alloc]init];
NSDictionary *outputSettings = @{AVVideoCodecKey:AVVideoCodecJPEG};
[_captureStillImageOutput setOutputSettings:outputSettings];//输出设置
//将设备输入添加到会话中
if ([_captureSession canAddInput:_captureDeviceInput]) {
[_captureSession addInput:_captureDeviceInput];
}
//将设备输出添加到会话中
if ([_captureSession canAddOutput:_captureStillImageOutput]) {
[_captureSession addOutput:_captureStillImageOutput];
}
//创建视频预览层,用于实时展示摄像头状态
_captureVideoPreviewLayer=[[AVCaptureVideoPreviewLayer alloc]initWithSession:self.captureSession];
CALayer *layer=self.viewContainer.layer;
layer.masksToBounds=YES;
_captureVideoPreviewLayer.frame=layer.bounds;
_captureVideoPreviewLayer.videoGravity=AVLayerVideoGravityResizeAspectFill;//填充模式
//将视频预览层添加到界面中
[layer addSublayer:_captureVideoPreviewLayer];
}
//拍照方法,需要一个返回值
- (void)takePhoto{
//根据设备输出获得连接
AVCaptureConnection *captureConnection=[self.captureStillImageOutput connectionWithMediaType:AVMediaTypeVideo];
//根据连接取得设备输出的数据
[self.captureStillImageOutput captureStillImageAsynchronouslyFromConnection:captureConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer) {
NSData *imageData=[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image=[UIImage imageWithData:imageData];
[self.imagesArray addObject:image];
}
}];
}
-(AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition )position{
NSArray *cameras= [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *camera in cameras) {
if ([camera position]==position) {
return camera;
}
}
return nil;
}
- (void)inductionFunction
{
[self initLabel];
self.motionManager = [[CMMotionManager alloc] init];
self.queue = [[NSOperationQueue alloc] init];
__block float rotationY = 0;
__block int count = 0;
if (self.motionManager.deviceMotionAvailable) {
__weak inductiveViewController *weakSelf = self;
self.motionManager.deviceMotionUpdateInterval = 0.1;
[self.motionManager startDeviceMotionUpdatesToQueue:self.queue withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) {
static NSDate *lastUpdateTime = nil;
//NSLog(@"%f",motion.rotationRate.y);
//更新UI在主线程
dispatch_async(dispatch_get_main_queue(), ^{
/***********这里图标的显示文字描述*************/
BOOL flag = YES;//flag为yes,可以显示右箭头,no为上升阶段,显示上箭头
float absPitch = ABS(motion.attitude.pitch - 1.56);
//动捕传感器可用且当前count拍照数小于13
if (count < 3) {
if (absPitch < 0.15)
{
//显示旋转箭头
[weakSelf initArrow:flag];
flag = NO;
[weakSelf initUpArrow:flag];
if (ABS(motion.rotationRate.y) > 0.085)
{
if (lastUpdateTime != nil)
{
NSTimeInterval secondSinceLastTime = [[NSDate date] timeIntervalSinceDate:lastUpdateTime];
//转换成角度而不是弧度显示
rotationY = rotationY + motion.rotationRate.y * secondSinceLastTime/M_PI *180;
//旋转了28度
if (ABS(rotationY) >=28)
{
[weakSelf takePhoto];
count++;
NSLog(@"count:%d ",count);
//NSLog(@"拍照时rotationY: %+.2f",rotationY);
rotationY = 0;
}
}
//更新时间
lastUpdateTime = [[NSDate alloc] init];
NSString *attitudeText = [NSString stringWithFormat:@"%+.2f",ABS(rotationY)];
weakSelf.GyrLabel.text = attitudeText;
}
//当y大于一定阈值时算检测到移动
}
else{
[weakSelf initUpArrow:flag];
flag = NO;
[weakSelf initArrow:flag];
}
} else {
/********超过13张************/
self.skipBtn.enabled = YES;
[self.view addSubview:self.skipBtn];
[self.skipBtn addTarget:self action:@selector(clickSkipBtn) forControlEvents:UIControlEventTouchUpInside];
}
});
}];
}
else{
}
[self.view addSubview:_GyrLabel];
}
//GCD结构
dispatch_queue_t queue = dispatch_queue_create(, DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
/**
放一些极其耗时间的任务在此执行
*/
dispatch_async(dispatch_get_main_queue(), ^{
/**
耗时任务完成,拿到资源,更新UI
更新UI只可以在主线程中更新
*/
});
});
八、图像拼接
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
self.panoImage = [CVWrapper processWithArray:self.MutaArray];
dispatch_async(dispatch_get_main_queue(), ^{
CGSize size = CGSizeMake(1024, 1024);
UIImage *newPanoImage = [self imageWithImageSimple:self.panoImage scaledToSize:size ];
//将cgimage添加到panorama上
[(PLCylindricalPanorama *)panorama setImage:[PLImage imageWithCGImage:newPanoImage.CGImage]];
//Add a hotspot
PLTexture *hotspotTexture = [PLTexture textureWithImage:[PLImage imageWithPath:[[NSBundle mainBundle] pathForResource:@"hotspot" ofType:@"png"]]];
PLHotspot *hotspot = [PLHotspot hotspotWithId:(kIdMin + random() % ((kIdMax + 1) - kIdMin)) texture:hotspotTexture atv:0.0f ath:0.0f width:0.08f height:0.08f];
[panorama addHotspot:hotspot];
[plView setPanorama:panorama];
});
});