[iOSUI进阶-2.3]彩票Demov1.3

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

A.需求

真机调试"关于”模块存储开关状态打电话、发短信应用评分打开其他应用cell 在iOS6 和 iOS7的适配block的循环引用屏幕适配code source: code source: https://github.com/hellovoidworld/HelloLottery

B.iOS真机测试小功能

(1)打电话

a.方法1

最简单最直接的方式:直接跳到拨号界面

1NSURL *url = [NSURL URLWithString:@"tel://10086"];2[[UIapplicationsharedApplication] openURL:url];

缺点

电话打完后,不会自动回到原应用,直接停留在通话记录界面

b.方法2

拨号之前会弹框询问用户是否拨号,拨完后能自动回到原应用

1NSURL *url = [NSURL URLWithString:@"telPRompt://10086"];2[[UIApplication sharedApplication] openURL:url];

缺点

因为是私有API,所以可能不会被审核通过

c.方法3

创建一个UIWebView来加载URL,拨完后能自动回到原应用

1if(_webView ==nil) {2_webView =[[UIWebView alloc] initWithFrame:CGRectZero];3}4[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"tel://10010"]]];

需要注意的是:这个webView千万不要添加到界面上来,不然会挡住其他界面

(2)发短信

a.方法1

直接跳到发短信界面,但是不能指定短信内容,而且不能自动回到原应用

1NSURL *url = [NSURL URLWithString:@"sms://10086"];2[[UIApplication sharedApplication] openURL:url];

b.方法2

#mark:

注意要写对代理名称messageComposeDelegate和mailComposeDelegate,不是delegate

如果想指定短信内容,那就得使用MessageUI框架

包含主头文件

#import <MessageUI/MessageUI.h>

显示发短信的控制器

1MFMessageComposeViewController *vc =[[MFMessageComposeViewController alloc] init];2//设置短信内容3vc.body =@"吃饭了没?";4//设置收件人列表5vc.recipients = @[@"10086",@"13800138000"];6//设置代理(这里使用block封装,由于强指针持有self,会有内存泄露)7vc.messageComposeDelegate =self;89//显示控制器10[self presentViewController:vc animated:YES completion:nil];

代理方法,当短信界面关闭的时候调用,发完后会自动回到原应用

1- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result2{3//关闭短信界面4[controller dismissViewControllerAnimated:YES completion:nil];56if(result ==MessageComposeResultCancelled) {7NSLog(@"取消发送");8}elseif(result ==MessageComposeResultSent) {9NSLog(@"已经发出");10}else{11NSLog(@"发送失败");12}13}

(3)发邮件

a.方法1

用自带的邮件客户端,发完邮件后不会自动回到原应用

1NSURL *url = [NSURL URLWithString:@"mailto://10010@QQ.com"];2[[UIApplication sharedApplication] openURL:url];

b.方法2

跟发短信的第2种方法差不多,只不过控制器类名叫做:MFMailComposeViewControlle

1//方法2:使用控制器2MFMailComposeViewController *mailController =[[MFMailComposeViewController alloc] init];34//发送主题5[mailController setSubject:@"重要作战会议"];67//邮件内容8[mailController setMessageBody:@"就是那个...该吃饭了吧"isHTML:NO];910//收件人11[mailController setToRecipients:@[@"hellovoidworld@163.com"]];1213//抄送人14[mailController setCcRecipients:@[@"hellovoidworld@163.com"]];1516//密送人17[mailController setBccRecipients:@[@"hellovoidworld@163.com"]];1819//附件20UIImage *image = [UIImage imageNamed:@"LoginScreen"];21NSData *data =UIImagePNGRepresentation(image);22[mailController addAttachmentData:data mimeType:@"image/png"fileName:@"attach.png"];2324//代理25mailController.mailComposeDelegate =shareController;2627//弹出mail控制器28[shareController presentViewController:mailController animated:YES completion:nil];

邮件发送后的代理方法回调,发完后会自动回到原应用

1- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error2{3//关闭邮件界面4[controller dismissViewControllerAnimated:YES completion:nil];56if(result ==MFMailComposeResultCancelled) {7NSLog(@"取消发送");8}elseif(result ==MFMailComposeResultSent) {9NSLog(@"已经发出");10}else{11NSLog(@"发送失败");12}13}

(4)打开其他常见文件

如果想打开一些常见文件,比如html、txt、PDF、PPT等,都可以使用UIWebView打开

只需要告诉UIWebView文件的URL即可

至于打开一个远程的共享资源,比如http协议的,也可以调用系统自带的Safari浏览器:

1NSURL *url = [NSURL URLWithString:@”http://www.baidu.com"];2[[UIApplication sharedApplication] openURL:url];

(5)应用跳转

有时候,需要在本应用中打开其他应用,比如从A应用中跳转到B应用

首先,应用app得有自己的URL地址(在Info.plist中配置)

例如:app应用的URL地址就是:hvw://com.ios.app

接着在某个应用中使用UIApplication完成跳转

1NSURL *url = [NSURL URLWithString:@"hvw://com.ios.app"];2[[UIApplication sharedApplication] openURL:url];

(6)应用评分

为了提高应用的用户体验,经常需要邀请用户对应用进行评分

应用评分无非就是跳转到AppStore展示自己的应用,然后由用户自己撰写评论

如何跳转到AppStore,并且展示自己的应用

方法1

1NSString *appid =@"444934666";2NSString *str =[NSString stringWithFormat:3@"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%@", appid];4[[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];

方法2

1NSString *str =[NSString stringWithFormat:2@"itms-apps://itunes.apple.com/cn/app/id%@?mt=8", appid];3[[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];

(7)真机调试步骤

真机调试的主要步骤

登录开发者主页

生成cer证书:cer是一个跟电脑相关联的证书文件,让电脑具备真机调试的功能

添加App ID:调试哪些app?

注册真机设备:哪台设备需要做真机调试?

生成MobileProvision文件:结合2、3、4生成一个手机规定文件

导入cer、MobileProvision文件

最终会得到2个文件

Cer文件:让电脑具备真机调试的功能

MobileProvision文件:哪台设备、哪些app、哪台电脑需要做真机调试?

C.实现

1.真机调试 - 分享功能

新浪微博分享短信分享邮件分享必须要打开系统自带的软件来进行

使用block代码来调用系统软件

1//2//HVWShareViewController.m3//HelloLottery4//5//Created by hellovoidworld on 15/1/9.6//Copyright (c) 2015年 hellovoidworld. All rights reserved.7//89#import"HVWShareViewController.h"10#import"HVWArrowSettingItem.h"11#import"HVWSettingGroup.h"12#import<MessageUI/MessageUI.h>1314@interfaceHVWShareViewController () <MFMessageComposeViewControllerDelegate, MFMailComposeViewControllerDelegate>1516@end1718@implementationHVWShareViewController1920- (void)viewDidLoad {21[super viewDidLoad];22//Do any additional setup after loading the view.2324//配置数据25HVWSettingItem *weiboShare = [HVWArrowSettingItem itemWithIcon:@"WeiboSina"title:@"新浪微博分享"];26HVWSettingItem *smsShare = [HVWArrowSettingItem itemWithIcon:@"SmsShare"title:@"短信分享"];2728//为了避免block内持有本控制器,导致内存泄露,先声明一个弱指针29__weak HVWShareViewController *shareController =self;3031smsShare.runningBlock = ^{32//方法1:只能打开短信窗口,不能指定内容33//NSURL *smsURL = [NSURL URLWithString:@"sms://10086"];34//[[UIApplication sharedApplication] openURL:smsURL];3536//方法2:37//获取短信发送控制器38if(![MFMessageComposeViewController canSendText])return;3940MFMessageComposeViewController *messageController =[[MFMessageComposeViewController alloc] init];4142//短信内容43messageController.body =@"吃饭了没有?";4445//收件人46messageController.recipients = @[@"10086"];4748//设置代理,特别注意代理是messageComposeDelegate,不是delegate49messageController.messageComposeDelegate =shareController;5051//显示控制器52[shareController presentViewController:messageController animated:YES completion:nil];53};5455HVWSettingItem *mailShare = [HVWArrowSettingItem itemWithIcon:@"MailShare"title:@"邮件分享"];56mailShare.runningBlock = ^{57//方法1:直接调用58//NSURL *mailURL = [NSURL URLWithString:@"mailto://hellovoidworld@163.com"];59//[[UIApplication sharedApplication] openURL:mailURL];6061//方法2:使用控制器62MFMailComposeViewController *mailController =[[MFMailComposeViewController alloc] init];6364//发送主题65[mailController setSubject:@"重要作战会议"];6667//邮件内容68[mailController setMessageBody:@"就是那个...该吃饭了吧"isHTML:NO];6970//收件人71[mailController setToRecipients:@[@"hellovoidworld@163.com"]];7273//抄送人74[mailController setCcRecipients:@[@"hellovoidworld@163.com"]];7576//密送人77[mailController setBccRecipients:@[@"hellovoidworld@163.com"]];7879//附件80UIImage *image = [UIImage imageNamed:@"LoginScreen"];81NSData *data =UIImagePNGRepresentation(image);82[mailController addAttachmentData:data mimeType:@"image/png"fileName:@"attach.png"];8384//代理85mailController.mailComposeDelegate =shareController;8687//弹出mail控制器88[shareController presentViewController:mailController animated:YES completion:nil];8990};9192HVWSettingGroup *group =[[HVWSettingGroup alloc] init];93group.items =@[weiboShare, smsShare, mailShare];94[self.data addObject:group];95}9697- (void)didReceiveMemoryWarning {98[super didReceiveMemoryWarning];99//Dispose of any resources that can be recreated.100}101102#pragmamark - MFMessageComposeViewControllerDelegate 代理方法103/** 关闭信息后*/104- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {105//关闭信息窗口106[controller dismissViewControllerAnimated:YES completion:nil];107108//检测发送情况109if(MessageComposeResultSent ==result) {110NSLog(@"成功发送!");111}elseif(MessageComposeResultFailed ==result) {112NSLog(@"发送失败!");113}elseif(MessageComposeResultCancelled ==result) {114NSLog(@"取消发送!");115}else{116NSLog(@"发生错误!");117}118}119120/** 关闭邮件后*/121- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {122[controller dismissViewControllerAnimated:YES completion:nil];123}124125@end

2.“关于”模块

使用self.tableView.headerView自定义组头部

(1)使用xib设计头部

(2)创建一个类“设置”界面控制器

应用评分

其实就是打开AppStore中相应的软件

协议头:itms-apps://

打电话

使用webView来打开URL

协议头:tel://

1//2//HVWAboutViewController.m3//HelloLottery4//5//Created by hellovoidworld on 15/1/8.6//Copyright (c) 2015年 hellovoidworld. All rights reserved.7//89#import"HVWAboutViewController.h"10#import"HVWArrowSettingItem.h"11#import"HVWSettingGroup.h"1213@interfaceHVWAboutViewController ()1415@end1617@implementationHVWAboutViewController1819- (void)viewDidLoad {20[super viewDidLoad];21//Do any additional setup after loading the view.2223//准备一个webView24UIWebView *webView =[[UIWebView alloc] initWithFrame:CGRectZero];25[self.view addSubview:webView];262728//配置item和group29HVWSettingItem *gradeSupport = [HVWArrowSettingItem itemWithTitle:@"评分支持"];3031//跳转到app store进行应用评分32gradeSupport.runningBlock = ^{33//其实这是网易新闻的app id34NSString *appid =@"425349261";35NSString *appStoreAddr = [NSString stringWithFormat:@"http://itunes.apple.com/app/id%@?mt=8", appid];36NSURL *appStoreURL =[NSURL URLWithString:appStoreAddr];37[[UIApplication sharedApplication] openURL:appStoreURL];38};3940HVWSettingItem *servicePhone = [HVWArrowSettingItem itemWithTitle:@"客服电话"];41NSString *phoneNumber =@"020-83568090";42servicePhone.subTitle =phoneNumber;4344servicePhone.runningBlock = ^{45NSURL *phoneURL = [NSURL URLWithString:[NSString stringWithFormat:@"tel://%@",phoneNumber]];46[webView loadRequest:[NSURLRequest requestWithURL:phoneURL]];47};4849HVWSettingGroup *group =[[HVWSettingGroup alloc] init];50group.items =@[gradeSupport, servicePhone];51[self.data addObject:group];5253//header54//配置header view55UINib *nib = [UINib nibWithNibName:@"HVWAboutHeader"bundle:[NSBundle mainBundle]];56UIView *view =[[nib instantiateWithOwner:nil options:nil] lastObject];57self.tableView.tableHeaderView =view;58self.tableView.tableHeaderView.frame =view.bounds;59}6061- (void)didReceiveMemoryWarning {62[super didReceiveMemoryWarning];63//Dispose of any resources that can be recreated.64}6566@end

#mark:

1.不要使用autolayout,不然header显示不正确

2.不能使用代理方法 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

发现这样设置的头部是从section==1才开始的

3.存储开关状态

(1)监听开关

(2)及时存储

(3)初始化读取数据

使用preferences存储,key是cell的title,value就是bool值

监听所有的“开关”类型cell,让“开关”类型的cell在开关改变值之后自动存储键值

HVWSettingCell:

1/** 创建“开关”类型的cell*/2- (UISwitch *)switchView {3if(nil ==_switchView) {4_switchView =[[UISwitch alloc] init];56//监听开关7[_switchView addTarget:self action:@selector(switchChange) forControlEvents:UIControlEventValueChanged];8}9return_switchView;10}1112/** 开关变化事件13* 存储开关状态到preferences14*/15- (void) switchChange {16NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];17//使用cell的title作为key,开关状态作为value18[defaults setBool:self.switchView.isOn forKey:self.item.title];19//立即存储20[defaults synchronize];21}2223/** 读取开关状态*/24-(BOOL) readSwitchStatus {25NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];26return[defaults boolForKey:self.item.title];27}

4.打开其他应用

一样使用openURL

(1)给要打开的app配置应用URL(可以配置多个)

a.info.plist:添加URL types

b.添加协议头(可以配置多个,也可以不配)

c.添加identifier

(2)打开应用/打开AppStore下载应用

所以应该配置两个URL:

打开应用URL下载应用URL

a.判断app是否已经安装

UIApplication中的方法: - (BOOL) canOpenURL:(NSURL *) url

这里使用素材带的json数据

HVWProductViewController

1#pragmamark <UICollectionViewDelegate>2/** 选择事件*/3- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {4HVWProduct *product =self.products[indexPath.item];56NSURL *appUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@", product.urlSchema, product.urlId]];7NSURL *appStoreUrl =[NSURL URLWithString:product.appStoreUrl];89UIApplication *application =[UIApplication sharedApplication];10//先判断是否存在此app11if([application canOpenURL:appUrl]) {12//打开app13[application openURL:appUrl];14}else{15//跳转到app store下载app16[application openURL:appStoreUrl];17}18}

5.cell的 iOS6 & iOS7的适配(这里是针对iOS6适配成iOS7的样式)

由于cell在iOS6和iOS7上cell的显示不一样,所以需要进行统一适配

a.tableView使用统一的自定义背景

使用自带小图进行平铺操作合成背景

<1>清空backgroundView(避免在group样式下屏蔽了backgroundColor)

<2>使用平铺设置backgroundColor

b.cell使用统一的背景

c.cell使用统一的选中背景

<1>重写初始化方法initWithStyle

<2>设置选中时背景,选中状态适当调整颜色

d.统一cell内子控件样式

<1>清除子控件背景颜色

e.调整cell宽度,消除两边空隙

重写cell的setFrame方法在iOS6及以下系统修改cell的位置尺寸,适配iOS7

f.加上cell之间的分隔线

iOS6中,cell中右部分的子控件不属于contentView,所以contentView的宽度是不定的每组的最后一行不需要分隔线

#mark:系统升级OSX10.10还有Xcode6之后,苹果似乎已经完全舍弃了iOS6,即使使用Xcode5下载了iOS6模拟器,打开后就是黑屏一片,不能使用。

6.block内的循环引用导致内存泄露

在block代码内,使用了强指针指向block所在的对象(例如self),导致循环引用,不能释放资源

将block内的对象引用设置为弱指针:使用"__weak"修饰符

注意:也不要使用强指针访问对象的属性

7.屏幕适配

Autoresizing属性:能够设置控件在不同尺寸屏幕下的大小

要先取消勾选Autolayout才能使用Autoresizing属性

四周的4条指示条:代表和边框的距离固定

中间的2条指示条:代表宽高的自动适配

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航