软硬件环境
首先把软硬件环境配置妥当,Xcode配置好自己喜欢的字体,颜色,当然还有快捷键。
软件环境:
- 黑苹果就拉倒吧,穷学生可以考虑旧款mini,可以添固态硬盘的,机械硬盘编译起来实在慢得难以忍受。
其他必不可少项:
- Cocoa pods- 管理第三方开源库
- Source Tree(如果你有玩git的话,可以用它来查看分支和提交记录啥的)
- Visualjmon和VisualXML(做网络开发前测试接口工具)
- Datum Free或者SQLPro for SQLite Read-Only(用于玩转数据库)
- 网易云音乐和耳机(免打扰神器)
硬件环境:
- 电脑、显示器这些就真的只能看老板财力了(传说中有钱的老板都标配Mac pro+超大显示器)
- 机械键盘和鼠标自配(这些不仅仅是游戏玩家的玩物,也是猿们的菜)
UI方面
控件封装
封装控件,暴漏接口处理信息显示和用户操作,这样做的好处不仅仅是让代码分布合理易维护,而且可提高代码复用率,使编码逻辑更清晰,后期维护成本更低;代理继承
首先明确一点:代理是可以继承的。
如Controller A比较复杂,其中包含一个collection view以支持左右滑动,而collection item中又包含了一个table view以支持上下滑动,而table view 的cell又有很多响应要处理。
这样问题就来了,如果table view cell中使用block向上层传递响应,则其只能先传递给collection item,而collection item再传递给Controller A,这就涉及到了两层传递,有点恶心了吧。很显然这样操作cell的每个block回调都需要item中有一个对应的block,这样操作可读性和易维护性都降低了,而且冗余。
另一种解决方案就是cell通过代理将响应向上传递给item,item再通过代理传递给Controller A,这样做的结果和使用block差不多,但是如果item的delegate继承自cell的代理,这种需要一一对应的糟心就从容化解了。需要注意的是itemDelegate要继承自cellDelegate,并且在item中把cell的代理设置为item的代理,item的代理设置为controller A,这样controller A只需要遵守itemDelegate就可以愉快的实现并响应cell的代理方法了。使用约束化解label的高度计算
之前最让我头疼的就是label的高度计算了,因为每次都要等到有值之后才能精确计算。因为label的高度不直接或间接的限制的话,它是可以随内容的多少自适应高度的(前提是numberOfLine == 0),这个就给label高度自适应提供了解决之道。
在此不多说,可以参考上篇博客。scroll view滚动
想让scroll view可以滚动,就设置contentSize.height大于其自身size.height吧table view的header停留在顶部的问题
这个只需要在初始化table view时将它设置成group类型的就行了(习惯new的也别new了,老老实实使用Apple提供的initWith方法)view透明度问题
如果设置view的alpha,则其子视图的透明度也会随之而变,这并不是我们想要的结果。
如果想把view设置成透明的,且其子试图不受影响,可以设置其颜色为clearColor
_v.backgroundColor = [UIColor clearColor];
如果想改变view的透明度,而不影响其子试图,可以这样设置其颜色,
_v.backgroundColor = [UIColor colorWithWhite:0.f alpha:0.5];
当然也可以用RGB值设置其他的半透明颜色
_v.backgroundColor = [UIColor colorWithRed:0.1 green:0.2 blue:0.3 alpha:0.5];
- 其他待总结
编码方面
- 文件名和方法名要见名知义;
- 给需要设置必要参数的controller或view添加便利构造器(initWith方法)和类方法;
- 宏定义字符串可使用静态敞亮替换,如果BOOL参数过多可考虑使用枚举替换;
- 如果一个字符串在其他类中使用(如notification name),定义字符串时使用类名做其前缀;如果该字符串仅在本类中使用,可使用K做其前缀。
.h文件
#import "ChatMessageModel.h"
extern NSString * const ChatVoiceManagerWillPlayAudioNotification;
extern NSString * const ChatVoiceManagerPlayerItemKey;
extern NSString * const ChatVoiceManagerMsgIdKey;
extern NSString * const ChatVoiceManagerErrorKey;
extern NSString * const ChatVoiceManagerAudioUrlKey;
extern NSString * const ChatVoiceManagerTimeIntervalKey;
extern NSString * const ChatVoiceManagerTimeTooShortResponse;
.m文件
#import "ChatVoiceManager.h"
NSString * const ChatVoiceManagerWillPlayAudioNotification = @"ChatVoiceManagerWillPlayAudioNotification";
NSString * const ChatVoiceManagerPlayerItemKey = @"ChatVoiceManagerPlayerItemKey";
NSString * const ChatVoiceManagerMsgIdKey = @"ChatVoiceManagerMsgIdKey";
NSString * const ChatVoiceManagerErrorKey = @"ChatVoiceManagerErrorKey";
NSString * const ChatVoiceManagerAudioUrlKey = @"ChatVoiceManagerAudioUrlKey";
NSString * const ChatVoiceManagerTimeIntervalKey = @"ChatVoiceManagerTimeIntervalKey";
NSString * const ChatVoiceManagerTimeTooShortResponse = @"time is too short";
- 可使用dispatch方法替换对应的performSelector: onThread;
- 使用respondsToSelector:可以判断某一对象是否响应某方法,包括“私有方法”(简单的理解为.h中没有定义的方法吧,其实OC中没有什么私有方法的,但是感觉这样比较好理解);
- 使用#pragma mark - <#option#>将.m中的文件分隔成不同的区,按住ctrl+6能看出其效果;
- 使用代码块
如果你不知道代码块是什么,请在.m文件的一个方法中敲出dispatchonce,看看Xcode会联想到什么,其实它联想到的这玩意儿就是代码块。
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
<#code to be executed once#>
});
如何添加代码块:
以#pragma mark - <#option#>为例
- 汉字转拼音,如下:
-(NSString *)changeChineneString:(NSString *)ChineseStr{
//转化为可变字符串
NSMutableString * str = [NSMutableString stringWithString:ChineseStr];
//转化函数
//带音调的拼音kCFStringTransformMandarinLatin
CFStringTransform((CFMutableStringRef)str, NULL, kCFStringTransformMandarinLatin, NO);
NSLog(@"%@",str);
//转化为不带音调的拼音
CFStringTransform((CFMutableStringRef)str, NULL, kCFStringTransformStripDiacritics, NO);
NSLog(@"%@",str);
return str;
}
使用command+option+?给方法或属性添加注释
如下注释:
平淡无奇是吗?看下面一张图
如果需要model的几个属性综合起来做判断,可以给model添加方法在model中处理该判断,直接返回BOOL值
- 其它待添加
常用却鲜为人知的Xcode快捷键
- command+系列
- command+shift+h -模拟器home键
- command+shift+o -快捷搜索
- command+shift+n -创建新工程
- command+shift+k -清理Xcode,这种做法会使下次编译过慢(慎用)
- command+shift+2 -打开设备管理器
- command+ctrl+上下 -切换.h/.m文件
command+option+[/] -将选中的代码区域(光标所在行)向上(下)移动一行
command系列
- command+上下 -将光标移动到文件的最上/下一行
- command+左右 -将光标移至某行的最左/右端
- command+delete -删除某一行光标之前的所有字符
- command+? -注释和解除注释
- command+option -选择一个矩形区域内的所有内容
- command+q -退出软件(这算是mac os的快捷键)
- command+o -打开工程目录
- command+9 -选中一个(组)文件,在目录中打开(哈哈,这是我自己添加的快捷键,如果需要你也可以按照自己的习惯改)
- command+, -打开Xcode preferences,去改设置吧
- 选择一段文本后按住command可以选择其它不相邻的文本
按住command点击方法/属性可跳转至其实现/定义的行
shift系列
按住shift可以选择光标所在行到鼠标指针所在行的所有内容
ctrl系列
- ctrl+6 -打开方法列表(.m中)/打开接口列表(.h中),ctrl+6后直接敲出关键字即可实现过滤
- 其它待添加
xib相关
- 关于拖出圆形view的问题
关于同一行的两个label内容显示优先问题
保证前面的label内容过长的时候不至于后面的label显示不出来
修改约束,修改约束的优先级(需要修改约束的优先级)
将约束拖出来,such as:
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageViewWidth;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *titleLabelCenterLayout;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *titleLabelTopLayout;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *titleLabelHeight;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageViewTopLayout;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageViewCenterLayout;
//愉快的修改约束
//修改约束优先级
_titleLabelCenterLayout.priority = UILayoutPriorityDefaultLow;
_titleLabelTopLayout.priority = UILayoutPriorityDefaultHigh+1;
_imageViewTopLayout.priority = UILayoutPriorityDefaultHigh+1;
_imageViewCenterLayout.priority = UILayoutPriorityDefaultHigh;
_titleTextLabelLeadingToGenderIcon.priority = UILayoutPriorityDefaultHigh+1;
_TitleTextLabelLeadingToSuperView.priority = UILayoutPriorityDefaultHigh;
//修改约束的指定的间距
_imageViewWidth.constant = 60;
_titleLabelHeight.constant = 21;
- 其它待添加