30, CocoaPods pod install/pod update更新慢的问题
pod install –verbose –no-repo-update
pod update –verbose –no-repo-update
如果不加后面的参数,默认会升级CocoaPods的spec仓库,加一个参数可以省略这一步,然后速度就会提升不少。
31,MRC和ARC混编设置方式
在XCode中targets的build phases选项下Compile Sources下选择 不需要arc编译的文件
双击输入 -fno-objc-arc 即可
MRC工程中也可以使用ARC的类,方法如下:
在XCode中targets的build phases选项下Compile Sources下选择要使用arc编译的文件
双击输入 -fobjc-arc 即可
32,把tableview里cell的小对勾的颜色改成别的颜色
_mTableView.tintColor = [UIColor redColor];
33,调整tableview的separaLine线的位置
tableView.separatorInset = UIEdgeInsetsMake(0, 100, 0, 0);
34,设置滑动的时候隐藏navigationbar
navigationController.hidesBarsOnSwipe = Yes
35,自动处理键盘事件,实现输入框防遮挡的插件
IQKeyboardManager
https://github.com/hackiftekhar/IQKeyboardManager
36,Quartz2D相关
图形上下是一个CGContextRef类型的数据。
图形上下文包含:
1,绘图路径(各种各样图形)
2,绘图状态(颜色,线宽,样式,旋转,缩放,平移)
3,输出目标(绘制到什么地方去?UIView、图片)
1,获取当前图形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
2,添加线条
CGContextMoveToPoint(ctx, 20, 20);
3,渲染
CGContextStrokePath(ctx);
CGContextFillPath(ctx);
4,关闭路径
CGContextClosePath(ctx);
5,画矩形
CGContextAddRect(ctx, CGRectMake(20, 20, 100, 120));
6,设置线条颜色
[[UIColor redColor] setStroke];
7, 设置线条宽度
CGContextSetLineWidth(ctx, 20);
8,设置头尾样式
CGContextSetLineCap(ctx, kCGLineCapSquare);
9,设置转折点样式
CGContextSetLineJoin(ctx, kCGLineJoinBevel);
10,画圆
CGContextAddEllipseInRect(ctx, CGRectMake(30, 50, 100, 100));
11,指定圆心
CGContextAddArc(ctx, 100, 100, 50, 0, M_PI * 2, 1);
12,获取图片上下文
UIGraphicsGetImageFromCurrentImageContext();
13,保存图形上下文
CGContextSaveGState(ctx)
14,恢复图形上下文
CGContextRestoreGState(ctx)
37,屏幕截图
// 1. 开启一个与图片相关的图形上下文
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size,NO,0.0);
// 2. 获取当前图形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 3. 获取需要截取的view的layer
[self.view.layer renderInContext:ctx];
// 4. 从当前上下文中获取图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 5. 关闭图形上下文
UIGraphicsEndImageContext();
// 6. 把图片保存到相册
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
37,左右抖动动画
//1, 创建核心动画
CAKeyframeAnimation *keyAnima = [CAKeyframeAnimation animation];
//2, 告诉系统执行什么动画。
keyAnima.keyPath = @”transform.rotation”;
keyAnima.values = @[@(-M_PI_4 /90.0 * 5),@(M_PI_4 /90.0 * 5),@(-M_PI_4 /90.0 * 5)];
// 3, 执行完之后不删除动画
keyAnima.removedOnCompletion = NO;
// 4, 执行完之后保存最新的状态
keyAnima.fillMode = kCAFillModeForwards;
// 5, 动画执行时间
keyAnima.duration = 0.2;
// 6, 设置重复次数。
keyAnima.repeatCount = MAXFLOAT;
// 7, 添加核心动画
[self.iconView.layer addAnimation:keyAnima forKey:nil];
38,CALayer 的知识
CALayer 负责视图中显示内容和动画
UIView 负责监听和响应事件
创建UIView对象时,UIView内部会自动创建一个图层(既CALayer)
UIView本身不具备显示的功能,是它内部的层才有显示功能.
CALayer属性:
position 中点(由anchorPoint决定)
anchorPoint 锚点
borderColor 边框颜色
borderWidth 边框宽度
cornerRadius 圆角半径
shadowColor 阴影颜色
contents 内容
opacity 透明度
shadowOpacity 偏移
shadowRadius 阴影半径
shadowColor 阴影颜色
masksToBounds 裁剪
39,性能相关
- 视图复用,比如UITableViewCell,UICollectionViewCell.
- 数据缓存,比如用SDWebImage实现图片缓存。
- 任何情况下都不能堵塞主线程,把耗时操作尽量放到子线程。
- 如果有多个下载同时并发,可以控制并发数。
- 在合适的地方尽量使用懒加载。
- 重用重大开销对象,比如:NSDateFormatter、NSCalendar。
- 选择合适的数据存储。
- 避免循环引用。避免delegate用retain、strong修饰,block可能导致循环引用,NSTimer也可能导致内存泄露等。
- 当涉及到定位的时候,不用的时候最好把定位服务关闭。因为定位耗电、流量。
- 加锁对性能有重大开销。
- 界面最好不要添加过多的subViews.
- TableView 如果不同行高,那么返回行高,最好做缓存。
- Viewdidload 里尽量不要做耗时操作。
40,验证身份证号码
//验证身份证号码
- (BOOL)checkIdentityCardNo:(NSString*)cardNo
{
if (cardNo.length != 18) {
return NO;
}
NSArray* codeArray = [NSArray arrayWithObjects:@”7”,@”9”,@”10”,@”5”,@”8”,@”4”,@”2”,@”1”,@”6”,@”3”,@”7”,@”9”,@”10”,@”5”,@”8”,@”4”,@”2”, nil];
NSDictionary* checkCodeDic = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@”1”,@”0”,@”X”,@”9”,@”8”,@”7”,@”6”,@”5”,@”4”,@”3”,@”2”, nil] forKeys:[NSArray arrayWithObjects:@”0”,@”1”,@”2”,@”3”,@”4”,@”5”,@”6”,@”7”,@”8”,@”9”,@”10”, nil]];
NSScanner* scan = [NSScanner scannerWithString:[cardNo substringToIndex:17]];
int val;
BOOL isNum = [scan scanInt:&val] && [scan isAtEnd];
if (!isNum) {
return NO;
}
int sumValue = 0;
for (int i =0; i
41,响应者链条顺序
1> 当应用程序启动以后创建 UIApplication 对象
2> 然后启动“消息循环”监听所有的事件
3> 当用户触摸屏幕的时候, “消息循环”监听到这个触摸事件
4> “消息循环” 首先把监听到的触摸事件传递了 UIApplication 对象
5> UIApplication 对象再传递给 UIWindow 对象
6> UIWindow 对象再传递给 UIWindow 的根控制器(rootViewController)
7> 控制器再传递给控制器所管理的 view
8> 控制器所管理的 View 在其内部搜索看本次触摸的点在哪个控件的范围内(调用Hit test检测是否在这个范围内)
9> 找到某个控件以后(调用这个控件的 touchesXxx 方法), 再一次向上返回, 最终返回给”消息循环”
10> “消息循环”知道哪个按钮被点击后, 在搜索这个按钮是否注册了对应的事件, 如果注册了, 那么就调用这个”事件处理”程序。(一般就是执行控制器中的”事件处理”方法)
42,使用函数式指针执行方法和忽略performSelector方法的时候警告
不带参数的:
SEL selector = NSSelectorFromString(@”someMethod”);
IMP imp = [_controller methodForSelector:selector];
void (func)(id, SEL) = (void )imp;
func(_controller, selector);
带参数的:
SEL selector = NSSelectorFromString(@”processRegion:ofView:”);
IMP imp = [_controller methodForSelector:selector];
CGRect (func)(id, SEL, CGRect, UIView ) = (void *)imp;
CGRect result = func(_controller, selector, someRect, someView);
忽略警告:
pragma clang diagnostic push #pragma clang diagnostic ignored “-Warc-performSelector-leaks”
[someController performSelector: NSSelectorFromString(@”someMethod”)]
pragma clang diagnostic pop
如果需要忽视的警告有多处,可以定义一个宏:
define SuppressPerformSelectorLeakWarning(Stuff)
do {
_Pragma(“clang diagnostic push”)
_Pragma(“clang diagnostic ignored “-Warc-performSelector-leaks”“)
Stuff;
_Pragma(“clang diagnostic pop”)
} while (0)
使用方法:
SuppressPerformSelectorLeakWarning(
[_target performSelector:_action withObject:self]
);
43,UIApplication的简单使用
——–设置角标数字——–
//获取UIApplication对象
UIApplication *ap = [UIApplication sharedApplication];
//在设置之前, 要注册一个通知,从ios8之后,都要先注册一个通知对象.才能够接收到提醒.
UIUserNotificationSettings *notice =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
//注册通知对象
[ap registerUserNotificationSettings:notice];
//设置提醒数字
ap.applicationIconBadgeNumber = 20;
——–设置联网状态——–
UIApplication *ap = [UIApplication sharedApplication];
ap.networkActivityIndicatorVisible = YES;