专栏首页向治洪iOS开发技巧篇

iOS开发技巧篇

在iOS开发中,有一些技巧可以提高程序猿的开发效率。

1,Xcode真机调试

Xcode 7推出之前,想要真机调试,iOS开发者必须花$99购买苹果开发者账号,而且步骤繁琐,需要下载证书认证。随着苹果公司推出了Xcode 7之后,大幅度的简化了真机调试的步骤。但是如果要测试推送等,还是需要证书的。

第一步:准备Mac电脑,Apple ID, iPhone手机,Xcode 集成开发环境; 第二步:打开Xcode选择屏幕左上角Xcode->Preferences->Account。

第三步,点击左下角的+按钮登陆Apple ID,登陆你的Apple ID,填写相关信息

第四步:打开需要真机测试的项目插上手机(Xcode第一次链接手机会很慢,可以选择Xcode菜单栏中的 window-> devices查看手机是否准备就绪了),选择 项目文件-> General - > Team-> 选择你属于你的Apple ID ,再点击Team 下面的fix issue修复Team 正下方的警告。 或者直接点击你的真机运行即可。

注:如果运行项目的时候弹出一个框(process launch failed: Security),则需要进行信任授权。依次点击设置->通用- >描述文件->选择你的Apple ID - >点击信任。

2,Xcode截屏

Xcode默认提供了截屏功能,在 Xcode的 debug菜单中找到viewDebugging,然后点击截屏选项,就可以将截屏的屏幕保存到桌面了。

3,code snippet

Xcode默认提供了非常丰富的代码片段可供选择,在实际开发中很多的提示就是一个代码片段,具体可以参加 Xcode 的右侧工具栏下方:

那如何创建自定义的代码段呢?很简单,首先在 Xcode 中写出你想创建的代码,然后选中拖动至上面图片的 code snippet library 中,这里有个技巧就是如果代码中有可变参数的话,可以用 <#parammeter#> 这样的形式包起来,比如我们经常创建的属性 property,首先在 Xcode 中写上:

@property (nonatomic, strong) <#UIView#> *<#myView#>;

然后选中这行代码,拖动到 code snippet library 中,然后你就会发现在代码段库的最底部生成了一个自定义的代码段,再进行编辑其 title,completion shortcut,如下:

点击右下角 Done 之后,再回到 Xcode 中键入 @property 你就回惊奇的发现刚才创建的代码段出现在代码自动提示列表中:

4,让 view 从屏幕顶部开始

iOS7 以后,有导航的话,controller 的 view 默认是会以导航栏的下方为起点开始,如果需要让它从屏幕顶部开始的话,只需要一句话就可以搞定。

 self.extendedLayoutIncludesOpaqueBars = YES;

5,屏幕旋转控制

假如应用中只有少数几个界面需要支持横屏时,我们不必打开设置文件进行配置,只需要按照下面的步骤添加一个BOOL属性即可。 (1) 首先在 appDelegate.h 中创建一个 BOOL 属性,当属性为YES时,就表示横屏。比如:

@property (nonatomic,assign)BOOL allowRotation; //是否支持横屏

然后到 appDelegate.m 中实现,

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window{

    if (self.allowRotation) {
        return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortrait ;
    }
    return UIInterfaceOrientationMaskPortrait;
}

(2) 在需要支持的页面中,修改 allowRotation 的值为 YES即可。

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    // 出现时可旋转
    ((AppDelegate *)[UIApplication sharedApplication].delegate).allowRotation = YES;
}

同样重要的是,在页面将要消失时修改为只支持竖屏:

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    // 消失时恢复竖屏
    ((AppDelegate *)[UIApplication sharedApplication].delegate).allowRotation = NO;
    // 立即变为竖屏
    [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationPortrait] forKey:@"orientation"];

(3) 上述代码实现的是自动旋转、如果需要强制旋转的的话,在上述把横屏打开的前提下,使用下面的代码即可进行强制的横屏或者竖屏。

// 竖屏
    [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationPortrait] forKey:@"orientation"];
    // 横屏
    [[UIDevice currentDevice] setValue:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight] forKey:@"orientation"];

(4) 对于有导航栏的,使用侧滑返回时可能会出现问题,于是需要在将要进入横屏时禁用侧滑返回手势,退出横屏时再开启即可。

// 屏幕即将旋转
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
//    NSLog(@"here: %@  %@", NSStringFromCGSize(size), coordinator);

    if (size.width > size.height) {
        // 横屏,禁用侧滑返回手势
    } else {
        //竖屏,开启侧滑返回手势  
    }
}

5,修改App 名称

一般 App名称默认就是工程名、开发 App 过程中假如想到更合适的名字,这时候除了修改工程名这个办法外,其实更优雅的操作是在 info.plist 中添加一个key(Bundle display name),Value 就是你需要的新名字。

6,添加音乐播放代码

应用中添加适当的音效,可以提高用户体验。如果要实现播放一小段的音效功能,代码如下:

// 比如添加一个:截图音效
    // 1. 定义要播放的音频文件的URL
    NSURL *screenshotURL = [[NSBundle mainBundle] URLForResource:@"captureVoice" withExtension:@"wav"];
    // 2. 注册音频文件(第一个参数是音频文件的URL 第二个参数是音频文件的SystemSoundID)
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)screenshotURL,&screenshotSound);
    // 3. 为crash播放完成绑定回调函数、可不绑定
    // AudioServicesAddSystemSoundCompletion(screenshot, NULL, NULL, (void*)completionCallback, NULL);
    // 4. 播放 ditaVoice 注册的音频 并控制手机震动
    // AudioServicesPlaySystemSound(screenshotSound); // 只播放声音
    // AudioServicesPlayAlertSound(screenshotSound); // 同时手机会震动
    // AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); // 控制手机振动

7,让 section header view 不悬停

当 UITableView 的 style 属性设置为 Plain 时,这个tableview的section header在滚动时会默认悬停在界面顶端。而有时候则需要不悬停的效果,怎么做呢?只需要重载scrollview的delegate方法即可。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat sectionHeaderHeight = 40;
    if (scrollView.contentOffset.y<=sectionHeaderHeight&&scrollView.contentOffset.y>=0) {
        scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
    } else if (scrollView.contentOffset.y>=sectionHeaderHeight) {
        scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
    }
}

8,屏幕截图并保存

系统为我们提供了截屏的功能,但是在应用中要实现截屏功能,怎么做呢?代码如下:

//snapshotImage 这个方法效率比较低,
- (UIImage *)snapshotImage {
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *snap = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return snap;
}
//iOS 7上UIView上提供了drawViewHierarchyInRect:afterScreenUpdates:来截图,速度比renderInContext:快15倍。
- (UIImage *)snapshotImageAfterScreenUpdates:(BOOL)afterUpdates {
    if ([self respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {
        return [self snapshotImage];
    }
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0);
    [self.view drawViewHierarchyInRect:self.view.bounds afterScreenUpdates:afterUpdates];
    UIImage *snap = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return snap;
}
//保存截图到相册
- (void)saveImageToPhotos:(UIImage *)image{
    UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
//状态回调
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
    if (!error) {
        NSLog(@"\n\n保存成功\n\n");
    } else {
        NSLog(@"\n\n保存失败\n\n");
    }
}

9,获得任意 view 相对于屏幕的 frame

使用下面的代码可以获得任意 view 相对于屏幕的 frame。

CGRect frame = [[UIApplication sharedApplication].keyWindow convertRect:CGRectMake(0, 0, targetView.frame.size.width, targetView.frame.size.height) fromView:targetView];

10,UIImage与字符串互转

使用下面的代码可以实现UIImage与字符串互转。

//图片转字符串  
-(NSString *)UIImageToBase64Str:(UIImage *) image  
{  
    NSData *data = UIImageJPEGRepresentation(image, 1.0f);  
    NSString *encodedImageStr = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];  
    return encodedImageStr;  
}
//
//字符串转图片  
-(UIImage *)Base64StrToUIImage:(NSString *)_encodedImageStr  
{  
    NSData *_decodedImageData   = [[NSData alloc] initWithBase64Encoding:_encodedImageStr];  
    UIImage *_decodedImage      = [UIImage imageWithData:_decodedImageData];  
    return _decodedImage;  
}  

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • jsoup详解

    json相信大家都用的多,jsonp我就一直没有机会用到,但也经常看到,只知道是“用来跨域的”,一直不知道具体是个什么东西。今天总算搞明白了。下面一步步来搞清...

    xiangzhihong
  • Google V8 引擎

    V8的前世今生 V8是JavaScript渲染引擎,第一个版本随着Chrome的发布而发布(具体时间为2008年9月2日)。在运行JavaScript之前,相比...

    xiangzhihong
  • Google V8引擎

    V8的前世今生 V8是JavaScript渲染引擎,第一个版本随着Chrome的发布而发布(具体时间为2008年9月2日)。在运行JavaScript之前,相比...

    xiangzhihong
  • 第二章、深入类和对象

    zhang_derek
  • SAP ABAP CDS view和HANA CDS view的区别

    这两种技术都是SAP提出的"Code pushdown"理念的具体实现。SAP ABAP CDS view位于ABAP应用服务器层,使用OPEN SQL,支持的...

    Jerry Wang
  • python-web.py开发入门(推荐) 原

    输入运行文件命令。(我这里pycharm2018.2不晓得为嘛terminal调整不了字间距,而且文件路径的/都变了,文字颜色也不晓得哪里能改,其他地方的显示都...

    晓歌
  • Python数据库操作之pymysql模块和sqlalchemy模块

    参考博客https://www.cnblogs.com/aylin/p/5770888.html

    林清猫耳
  • Python装饰器的应用场景代码总结

    带参数的装饰器相当于一个返回装饰器的函数,@deco(a=1)在调用@之前会首先执行deco(a=1)得到一个实际的装饰器, 带参数的装饰器deco(a=1)模...

    砸漏
  • 【干货】动手实践:理解和优化GAN(附代码)

    【导读】本文是机器学习研究员Mirantha Jayathilaka撰写的一篇技术博文,主要讲解了生成对抗网络(GAN)。本文分别从理论和代码实践两方面来介绍G...

    WZEARW
  • 0x9 Python教程:命令自动化

    本教程将介绍一些自动执行OS命令的Python技术。我们将展示使用Python(os,subprocess)执行命令的两种方法。

    重生信息安全

扫码关注云+社区

领取腾讯云代金券