一些小的功能点,虽然很小,但是里面有些弯,值得注意。(同系列文章会持续更新.......)
1.tableHeaderView的使用:
这个效果的实现有种比较巧妙的地方:
self.HeadImgView= [[UIImageViewalloc]initWithFrame:CGRectMake(0,0,Width,HeadImgHeight)];
self.HeadImgView.image= [UIImageimageNamed:@"eee"];
[self.tableView addSubview:self.HeadImgView];
//与图像高度一样防止数据被遮挡
self.tableView.tableHeaderView= [[UIViewalloc]initWithFrame:CGRectMake(0,0,Width,HeadImgHeight)];
然后在scrollViewDidScroll 的代理方法中根据 sc 的偏移来动态的改变 self.HeadImgView 的 frame就可以达到这样的效果了。
但是,这里有个弯,如果不是把这个试图 addSubview 在tableView 上的话,直接
self.tableView.tableHeaderView= self.HeadImgView
的话,在代理中再改变 self.HeadImgView的 frame 就会出现下拉时上面出现空白的情况。
2.在导航条上放视图,点击字体变大:
往导航条上加试图的关键点:
self.navigationItem.titleView= view;(这个view 是 UIScrollView)也就是上面的标题区域
放缩关键点:
bgview.transform=CGAffineTransformScale(CGAffineTransformIdentity,0.85,0.85);
或者 bgview.transform=CGAffineTransformMakeScale(0.85, 0.85);
3.上滑显示和隐藏导航条:
NavigationBar他背后是有一张类型为_UINavigationBarBackground(UIImageView的子类)的视图,我们平时看到的大部分其实都是它,第二个箭头那里的ImageView就是那根细线,他是加在我们背景的ImageView上面的,我们设置BackgroundImage其实就是设置_UINavigationBarBackground的image。
设置导航条变透明:
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
设置导航条下的那条线隐藏起来:(这三条都实现才行)
方法一:
[self.navigationController.navigationBar setBackgroundImage:[UIImage new]forBarMetrics:UIBarMetricsDefault];//这样带来的坏处是导航条会占位64像素
self.navigationController.navigationBar.shadowImage= [UIImage new];
self.navigationController.navigationBar.translucent=NO;
方法二:
//递归查找出那条线
navBarHairlineImageView = [[MethodTool shareTool] findHairlineImageViewUnder:self.navigationController.navigationBar];
//隐藏
navBarHairlineImageView.hidden = YES;
实现这个效果的关键点:
barImageView=self.navigationController.navigationBar.subviews.firstObject;//用一个全局的指针,指向那个 imageView,根据表的y值上的偏移量,要动态的改变 这个imageview的 透明度即可,。
- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
NSLog(@"YYYY:%f",scrollView.contentOffset.y);
CGFloatoffset = scrollView.contentOffset.y;
CGFloatalpha = (offset/100);
barImageView.alpha= alpha;
}
PS:其实可以用一个自定义的导航条,根据表的偏移量要动态的改变自定义试图的透明度。。
4.隐藏导航条下的细线(两种方法):
(1)
[self.navigationController.navigationBarsetBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage= [UIImage new];
self.navigationController.navigationBar.translucent=NO;
这种方式有个副作用就是他回使导航条占64个像素,如果是整个项目都做完之后使用这种方法隐藏的话需要修改全局 试图的 Y坐标起始点是 0 而不是原来的64 ,所以建议 设置一个全局的宏定义 NAVHEIGHT 导航条的高度,来随时更改,更可控更方便
(2)
UIImageView *navBarHairlineImageView;//一个全局的指针
navBarHairlineImageView= [selffindHairlineImageViewUnder:self.navigationController.navigationBar];
navBarHairlineImageView.hidden=YES;
//使用了一个递归调用找到那个1像素高度的线,并隐藏它
- (UIImageView*)findHairlineImageViewUnder:(UIView*)view {
if([view isKindOfClass:UIImageView.class] && view.bounds.size.height<=1.0) {
return(UIImageView*)view;
}
for(UIView*subview in view.subviews) {
UIImageView*imageView = [self findHairlineImageViewUnder:subview];
if(imageView) {
returnimageView;
}}returnnil;
}
5.点击旋转全屏显示:
- (void)frameChange:(UIButton*)sender {
NSIntegeri = sender.tag;
if(!sender.selected) {
sender.selected=YES;
origanRect=viewPlay[i].frame;
origanSuperV=viewPlay[i].superview;
[UIViewbeginAnimations:nilcontext:nil];
[UIViewsetAnimationDuration:0.3];
viewPlay[i].transform=CGAffineTransformMakeRotation(M_PI*(90)/180.0);
viewPlay[i].bounds=CGRectMake(0,0,HEIGHT,WIDTH);
viewPlay[i].center=CGPointMake(WIDTH/2,HEIGHT/2);
[[UIApplicationsharedApplication].keyWindowaddSubview:viewPlay[i]];
[UIViewcommitAnimations];
sender.frame=CGRectMake(0,0,CGRectGetHeight(viewPlay[i].frame),CGRectGetWidth(viewPlay[i].frame));
}else{
sender.selected=NO;
[UIViewbeginAnimations:nilcontext:nil];
[UIViewsetAnimationDuration:0.3];
viewPlay[i].transform=CGAffineTransformMakeRotation(0);
viewPlay[i].frame=origanRect;
[origanSuperVaddSubview:viewPlay[i]];
[UIViewcommitAnimations];
sender.frame=CGRectMake(0,0,CGRectGetWidth(viewPlay[i].frame),CGRectGetHeight(viewPlay[i].frame));
}
}
UIView*viewPlay[PAGECOUNT*PAGEVIEWCOUNT]; 声明一个数组行的UIview 组。
viewPlay[i].center的设置很重要,不管是使用 viewPlay[i].bounds 还是 viewPlay[i].frame 都需要设置,是因为 系统自带的旋转是按照一段弧形的轨迹而不是中心点旋转,如果不设置
个人更推荐第二个
6.使用 UICollectionView 来展示图片多选:
图片多选择中使用 UICollectionView 来展示图片,好处:展示简单,删除更简单。
实现关键点:
-(UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath{
**最后一个item**
if(indexPath.item==arrayImages.count) {
CleandarCollectionViewCell*cell = [collectionViewdequeueReusableCellWithReuseIdentifier:@"CleandarCollectionViewCell"fo rIndexPath:indexPath];
cell.imgV.image= [UIImageimageNamed:@"add_photo"];
cell.backgroundColor= [UIColorgrayColor];
returncell;
}
**其他item**
CleandarCollectionViewCell*cell = [collectionViewdequeueReusableCellWithReuseIdentifier:@"CleandarCollectionViewCell"forIndexPath:indexPath];
[cell.imgVsetImage:arrayImages[indexPath.item]];
returncell;
}
-(void)collectionView:(UICollectionView*)collectionView didSelectItemAtIndexPath:(NSIndexPath*)indexPath{
[self.viewendEditing:YES];
**最后一个**
if(indexPath.item==arrayImages.count) {
UIActionSheet*sheet = [[UIActionSheetalloc]initWithTitle:@"相片来源"delegate:selfcancelButtonTitle:@"取消"destructiveButtonTitle:nilotherButtonTitles:@"相机",@"相册",nil];
[sheetshowInView:self.view];
}else{
UIAlertController*alertController = [UIAlertControlleralertControllerWithTitle:@"确定删除该张图片"message:nilpreferredStyle:UIAlertControllerStyleAlert];
UIAlertAction*action = [UIAlertActionactionWithTitle:@"是"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction*action) {
[arrayImagesremoveObject:arrayImages[indexPath.item]];
[self.collectionreloadData];
}];
[alertControlleraddAction:action];
UIAlertAction*actionDelete = [UIAlertActionactionWithTitle:@"否"style:UIAlertActionStyleDefaulthandler:^(UIAlertAction*action) {
}];
[alertControlleraddAction:actionDelete];
[selfpresentViewController:alertControlleranimated:YEScompletion:nil];
}
[self.collection reloadData];
}
7.类似滴滴打车软件中左边侧滑时动态隐藏 状态栏:
相信细心的朋友会发现,状态栏是动态隐藏了,可是由于缺少状态栏的20像素,造成了背部的视图整体上移了20像素,我使用的是系统自带的导航栏,也尝试了动态增加 导航栏的高度从44变为64,可是总有瞬间形变造成的不自然感,最后细心研究发现**滴滴打车是自定义的导航栏**,所以我使用的方法是没错的,只要需要的时候使用自定义的导航栏就可以达到 跟 滴滴打车一样的效果啦。
关键代码:
(1) View controller-based status bar appearance设为NO,这时application的设置优先级最高,用下面的方式隐藏status bar:
[[UIApplicationsharedApplication]setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
(2)如果View controller-based status bar appearance设为YES。这时view controller中对status bar的设置优先级高于application的设置,用下面的方式隐藏status bar:
1、在view controller中调用setNeedsStatusBarAppearanceUpdate,更新status bar的显示。
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
[self prefersStatusBarHidden];
[self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)];
}}
2、覆盖view controller的prefersStatusBarHidden的实现,返会YES。
- (BOOL)prefersStatusBarHidden
{
return YES;
}
就可以达到动态隐藏和显示状态栏的目的。
8.朗读文字
使用到的是 iOS 原声的 AVFoundation.framework 里面的API。
使用到的类是 :AVSpeechSynthesizer 里面包括 开始、暂停、继续朗读等功能。
所有的嗓音如下:
"[AVSpeechSynthesisVoice 0x978a0b0] Language: th-TH",
"[AVSpeechSynthesisVoice 0x977a450] Language: pt-BR",
"[AVSpeechSynthesisVoice 0x977a480] Language: sk-SK",
"[AVSpeechSynthesisVoice 0x978ad50] Language: fr-CA",
"[AVSpeechSynthesisVoice 0x978ada0] Language: ro-RO",
"[AVSpeechSynthesisVoice 0x97823f0] Language: no-NO",
"[AVSpeechSynthesisVoice 0x978e7b0] Language: fi-FI",
"[AVSpeechSynthesisVoice 0x978af50] Language: pl-PL",
"[AVSpeechSynthesisVoice 0x978afa0] Language: de-DE",
"[AVSpeechSynthesisVoice 0x978e390] Language: nl-NL",
"[AVSpeechSynthesisVoice 0x978b030] Language: id-ID",
"[AVSpeechSynthesisVoice 0x978b080] Language: tr-TR",
"[AVSpeechSynthesisVoice 0x978b0d0] Language: it-IT",
"[AVSpeechSynthesisVoice 0x978b120] Language: pt-PT",
"[AVSpeechSynthesisVoice 0x978b170] Language: fr-FR",
"[AVSpeechSynthesisVoice 0x978b1c0] Language: ru-RU",
"[AVSpeechSynthesisVoice 0x978b210] Language: es-MX",
"[AVSpeechSynthesisVoice 0x978b2d0] Language: zh-HK", 中文(香港) 粤语
"[AVSpeechSynthesisVoice 0x978b320] Language: sv-SE",
"[AVSpeechSynthesisVoice 0x978b010] Language: hu-HU",
"[AVSpeechSynthesisVoice 0x978b440] Language: zh-TW", 中文(台湾)
"[AVSpeechSynthesisVoice 0x978b490] Language: es-ES",
"[AVSpeechSynthesisVoice 0x978b4e0] Language: zh-CN", 中文(普通话)
"[AVSpeechSynthesisVoice 0x978b530] Language: nl-BE",
"[AVSpeechSynthesisVoice 0x978b580] Language: en-GB", 英语(英国)
"[AVSpeechSynthesisVoice 0x978b5d0] Language: ar-SA",
"[AVSpeechSynthesisVoice 0x978b620] Language: ko-KR",
"[AVSpeechSynthesisVoice 0x978b670] Language: cs-CZ",
"[AVSpeechSynthesisVoice 0x978b6c0] Language: en-ZA",
"[AVSpeechSynthesisVoice 0x978aed0] Language: en-AU",
"[AVSpeechSynthesisVoice 0x978af20] Language: da-DK",
"[AVSpeechSynthesisVoice 0x978b810] Language: en-US", 英语(美国)
"[AVSpeechSynthesisVoice 0x978b860] Language: en-IE",
"[AVSpeechSynthesisVoice 0x978b8b0] Language: hi-IN",
"[AVSpeechSynthesisVoice 0x978b900] Language: el-GR",
"[AVSpeechSynthesisVoice 0x978b950] Language: ja-JP" )
代码:
#import
// 创建嗓音,指定嗓音不存在则返回nil
AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];
// 创建语音合成器
AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init];
// 实例化发声的对象
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:@"朗读完毕"];
utterance.voice = voice;
utterance.rate = 0.5; // 语速
speech.pitchMultiplier=1; //音高 越高声音越尖
speech.postUtteranceDelay=0.1f;//目的是让语音合成器播放下一语句前有短暂的暂停
speech.volume=1; //音量
[synthesizer speakUtterance:utterance]; // 朗读的内容
如果提示这种错误:
|AXSpeechAssetDownloader|error| ASAssetQuery error fetching results (for com.apple.MobileAsset.MacinTalkVoiceAssets) Error Domain=ASError Code=21 "Unable to copy asset information" UserInfo={NSDescription=Unable to copy asset information}
请去iPhone里设置:
进入iPhone的 设置 > 通用 > 辅助功能 > 语音,开启“朗读所选项”,并在“嗓音”中选择“中文”
在真机测试的时候,碰巧那台手机的加减音量按键失效了,于是在手机设置里把音量调到最大,可是在测试的时候还是音量很小,最后换了一台手机,在测试的时候使用+-键加大了音量,声音果然大了起来,才发现手机设置-> 声音-> 设置的声音大小是来电铃声的音量大小,并不是扬声器的音量。+-键才能设置的是扬声器的音量。
9.语音转文字
使用的是第三方 科大讯飞的SDK github 地址
10.别人的模拟器运行起我们开发的app
场景:无法真机装app| 公司的UUID 已经使用完了 |
解决办法:
解决思路,想要别人的模拟器运行起我们开发的app,最简单的办法就是把我们DerivedData的数据直接拷贝到别人模拟器上面,就可以了。
ditto -ck --sequesterRsrc --keepParent `ls -1 -d -t ~/Library/Developer/Xcode/DerivedData/*/Build/Products/*-iphonesimulator/*.app | head -n 1`
我们运行完上面的ditto命令会产生一个zip文件,解压出来,会得到一个app文件,这个就是debug包了。debug包就是我们要给设计师的app包了。
如何能让设计师傻瓜式的安装这个app呢?这里介绍一个命令行工具,ios-sim命令行工具。
ios-sim 是一个可以在命令控制iOS模拟器的工具。利用这个命令,我们可以启动一个模拟器,安装app,启动app,查询iOS SDK。它可以使我们像自动化测试一样不用打开Xcode。
原文链接