├── .gitignore ├── 0_Foundation ├── #program常用标识.md ├── IOS多线程技术.md ├── IOS绘图.md ├── JavascriptCore使用.md ├── NSBundle获取不到文件路径.md ├── NSJSONReadingOptions类型说明.md ├── NSLog的格式.md ├── NSString常用方法.md ├── Notification和KVO.md ├── Objectc 中__attribute__的用法.md ├── Swizzling.md ├── URL编码.md ├── USURL用法.md ├── cocoa基础.md ├── cookie操作.md ├── https请求处理-信任一切证书.md ├── ios9支持http请求.md ├── ios中bundle的使用.md ├── ios开发的系统兼容性问题解决.md ├── json对象处理.md ├── objc 验证参数有效性的方法.md ├── objc二进制数据处理.md ├── objc代码块的使用.md ├── objective 和swift混搭使用.md ├── objective-c中模拟c语言的函数调用方法.md ├── runtime常用方法.md ├── strong和copy的使用区别.md ├── switf语法速记.md ├── weakSelf和strongSelf.md ├── while使用runloop阻塞方法返回.md ├── xcode中混用arc和非arc模式.md ├── xcode导入外部项目.md ├── xcode调试技巧.md ├── xcode静态库使用.md ├── 从本地plist文件中加载数据.md ├── 保存照片和视频到相册.md ├── 全局使用appDelegate中的方法.md ├── 共享对象的使用.md ├── 内存警告一般处理.md ├── 常用类型转换.md ├── 弃用的方法注释.md ├── 深复制和浅复制.md └── 类簇class cluster.md ├── 1_UIKit ├── 3D touch主屏幕添加快捷action方法.md ├── 3Dtouch系统图标类型.md ├── UIScrenn_UIView_UIWindow.md ├── UIView动画.md ├── iOS修改状态栏样式.md ├── presention和presenting通信.md ├── view图层层级.md ├── 半透明模态弹出框.md ├── 常用获取屏幕尺寸方法.md ├── 手势.md ├── 控件 │ ├── UIAlertController使用.md │ ├── UIImageView添加点击事件.md │ ├── UIImageView的contentMode属性.md │ ├── UIScrollView使用技巧.md │ ├── UISpiltViewController用法.md │ ├── UIViewController添加子controller控制.md │ ├── activityindactor的使用.md │ ├── controller导航 │ │ ├── UINavigationController使用.md │ │ ├── storyboard导航结构使用.md │ │ ├── tabbarNavition.md │ │ ├── tabbar和navigation混用.md │ │ └── 页面跳转和传值.md │ ├── ios获取系统信息.md │ ├── tableview │ │ ├── MyTableViewController.h │ │ ├── MyTableViewController.m │ │ ├── MyTableViewController.xib │ │ ├── UISearchController用法.md │ │ ├── tableview基本用法.md │ │ └── tableview常见问题.md │ ├── view强制横屏_支持arc.md │ ├── 修改searchBar的cancel文字.md │ ├── 打电话、发短信、email.md │ ├── 照相功能的使用.md │ ├── 警告控件使用.md │ ├── 进度条和定时器的使用.md │ └── 键盘出现和隐藏.md └── 样式 │ ├── UILabel_Attributes.md │ ├── UILabel使用例子.md │ ├── uiview超出部分不显示.md │ ├── 图片的拉伸.md │ └── 圆角imageview.md ├── 2_ThirdParty ├── AFNetworking使用.md ├── CocoaLumberjack的使用.md ├── MJRefreash的使用.md ├── REMenu使用.md ├── RestKit使用.md ├── SDWebImage使用.md ├── SVProgressHUD的使用.md ├── SVPullToRefresh使用.md ├── facebook:pop的使用.md ├── github上前100的ios项目.md ├── json-framework的使用.md └── 第三方常用库.md ├── 3_Other ├── aes128加密解密.md ├── iOS使用sha.md ├── iOS设计模式.md ├── ios单元测试.md ├── js和ios互相调用的性能研究.md ├── lldb调试.md ├── plist所有的key说明.md ├── xcode Code Snippets Library的使用.md ├── xcode利用target实现多版本管理.md ├── xcode常用快捷键整理.md ├── xcode插件.md ├── 先于main函数之前执行的代码段.md ├── 常见项目编译问题.md ├── 开发者账号和证书 │ ├── AppStore发布成功后如何找到应用的下载地址.md │ ├── IOS 真机调试.md │ ├── Xcode因为证书问题常见错误.md │ ├── failed to locate or generate matching signing assets错误解决办法.md │ ├── 企业app发布.md │ └── 新版itunesconnect__App注册及申请、发布流程说明文档.pdf ├── 推送服务 │ ├── Program.cs │ └── iOS消息推送实现.md ├── 根据不同ios版本实现不同逻辑.md ├── 编码习惯.md └── 预编译 │ ├── iOS开发中那些高效常用的宏.md │ ├── iOS预编译pch文件的使用.md │ └── ios宏的使用.md ├── 4_Study ├── ios学习技术栈.md ├── ios学习网站.md └── 好文阅读推荐.md ├── LICENSE ├── README.md ├── ios学习网站.md └── res ├── 1418798425343723.png ├── 1418798425648696.png └── 4F9EFDD7-E466-4BE3-8A50-DDC42C91E7E7.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.txt 2 | *.doc 3 | *.docx 4 | 5 | -------------------------------------------------------------------------------- /0_Foundation/#program常用标识.md: -------------------------------------------------------------------------------- 1 | ## ````#program常用标识 ```` 2 | 3 | ## 1:注释代码段 4 | --- 5 | 6 | ```` 7 | #program mark -[注释内容] 8 | 说明:用于注释内容 9 | #program mark 是每个ios程序员都必须会用的技巧,通过#program mark 把代码分为个个部分,良好的注释是好代码的开始 10 | ```` 11 | 12 | ## 2:取消xcode编译器内对于启用方法的警告 13 | --- 14 | 15 | ```` 16 | #pragma clang diagnostic push 17 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" 18 | // 这段中出现使用所有的弃用方法都不会产生告警 19 | #pragma clang diagnostic pop 20 | 21 | ```` 22 | 23 | ## 3:取消对未使用变量的警告,使用法师和2相同,必须成对出现#pragma clang 24 | --- 25 | 26 | ```` 27 | diagnostic --- 28 | #pragma clang diagnostic ignored "-Wunused-variable" 29 | 30 | ==================== 31 | #warning :手动产生一条告警 32 | #error : 手动产生一条错误 33 | ```` 34 | 35 | 还有种方式也能达到同样效果 36 | 37 | ```` 38 | #pragma unused (foo) 39 | 40 | ```` 41 | 42 | ## 4: 忽略内存泄露告警 43 | --- 44 | 45 | ```` 46 | #pragma clang diagnostic push 47 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 48 | [someController performSelector: NSSelectorFromString(@"someMethod")] 49 | #pragma clang diagnostic pop 50 | ```` -------------------------------------------------------------------------------- /0_Foundation/IOS多线程技术.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 1:performSelector 多线程 4 | 5 | ````objc 6 | /* 7 | *使用performSelector 的多线程 8 | *优点:简单 9 | *缺点:没有串行并线队列,不能实现高级线程调度 10 | */ 11 | 12 | -(void)performSelectorFunction{ 13 | 14 | NSLog(@"performSelectorFunction start"); 15 | 16 | //同步方式执行 17 | //[self performSelector:@selector(function1)]; 18 | 19 | //延迟两秒执行,主线程阻塞 20 | //[self performSelector:@selector(function1) withObject:nil afterDelay:2]; 21 | 22 | //主线程上执行,主线程阻塞,waitUntilDone:YES:等待执行完成顺序执行,waitUntilDone:NO 现执行后面语句 23 | //[self performSelectorOnMainThread:@selector(function1) withObject:nil waitUntilDone:NO]; 24 | 25 | //子线程上执行 26 | [self performSelectorInBackground:@selector(function1) withObject:nil]; 27 | 28 | NSLog(@"performSelectorFunction end"); 29 | 30 | } 31 | 32 | ```` 33 | 34 | ## 2:NSThread 35 | 36 | ````objc 37 | /* 38 | *使用NSThread 的多线程 39 | *优点:简单 40 | *缺点:没有串行并线队列,不能实现高级线程调度,和performSelector是一样的。 41 | */ 42 | 43 | -(void)NSThreadFunction{ 44 | 45 | NSLog(@"NSThreadFunction start"); 46 | 47 | //线程暂停 2秒 48 | //[NSThread sleepForTimeInterval:2]; 49 | 50 | //显示创建的方式执行 51 | //NSThread *myThread = [[NSThread alloc]initWithTarget:self selector:@selector(function1) object:nil]; 52 | //[myThread start]; 53 | 54 | //静态方法执行线程 55 | //[NSThread detachNewThreadSelector:@selector(function1) toTarget:self withObject:nil]; 56 | 57 | NSLog(@"NSThreadFunction end"); 58 | 59 | } 60 | 61 | ```` 62 | 63 | 64 | ## 3:NSTimer(反面教材,他不是多线程,他只是定时执行任务) 65 | 66 | ````objc 67 | /* 68 | *使反面教材,他不是多线程,他只是定时执行任务 69 | */ 70 | 71 | -(void)NSTimerFunction{ 72 | 73 | NSLog(@"NSTimerFunction start"); 74 | 75 | //定时执行任务,可以重复和不重复 76 | NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(function1) userInfo:nil repeats:NO]; 77 | 78 | //暂时停止定时器 79 | //[timer setFireDate:[NSDate distantFuture]]; 80 | //重新开启定时器 81 | //[timer setFireDate:[NSDate distantPast]]; 82 | //永久通知定时器 83 | //[timer invalidate]; 84 | //timer = nil; 85 | 86 | NSLog(@"NSTimerFunction end"); 87 | 88 | } 89 | 90 | ```` 91 | 92 | ## 4:GCD最棒的多线程使用api 93 | > GCD 中主要的对象: 94 | 95 | - dispatch_sync 96 | - dispatch_async 97 | - dispatch_once_t 98 | - dispatch_after 99 | - dispatch_queue_t 100 | - dispatch_group_async 101 | - dispatch_barrier_async 102 | - dispatch_apply 103 | - dispatch_suspend,dispatch_resume 104 | - dispatch_sync 105 | - dispatch_sync 106 | - dispatch_sync 107 | 108 | 109 | ````objc 110 | 111 | // dispatch_sync 同步方式执行: 112 | dispatch_sync(dispatch_get_global_queue(0, 0), ^{ 113 | // something 114 | }); 115 | 116 | 117 | // dispatch_async 异步执行: 118 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 119 | // something 120 | }); 121 | 122 | // dispatch_async:主线程执行: 123 | dispatch_async(dispatch_get_main_queue(), ^{ 124 | // something 125 | }); 126 | 127 | // dispatch_once:一次性执行: 128 | static dispatch_once_t onceToken; 129 | dispatch_once(&onceToken, ^{ 130 | // code to be executed once 131 | }); 132 | 133 | //dispatch_time_t :延迟2秒执行: 134 | double delayInSeconds = 2.0; 135 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 136 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 137 | // code to be executed on the main queue after delay 138 | }); 139 | 140 | //dispatch_group_t: 合并汇总结果 141 | dispatch_group_t group = dispatch_group_create(); 142 | dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ 143 | // 并行执行的线程一 144 | }); 145 | dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ 146 | // 并行执行的线程二 147 | }); 148 | dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{ 149 | // 汇总结果 150 | }); 151 | 152 | 153 | //dispatch_barrier_async :作用是在并行队列中,等待前面的队列执行完成后在继续往下执行 154 | dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT); 155 | dispatch_async(concurrentQueue, ^(){ 156 | NSLog(@"dispatch-1"); 157 | }); 158 | dispatch_async(concurrentQueue, ^(){ 159 | NSLog(@"dispatch-2"); 160 | }); 161 | dispatch_barrier_async(concurrentQueue, ^(){ 162 | NSLog(@"dispatch-barrier"); 163 | }); 164 | dispatch_async(concurrentQueue, ^(){ 165 | NSLog(@"dispatch-3"); 166 | }); 167 | dispatch_async(concurrentQueue, ^(){ 168 | NSLog(@"dispatch-4"); 169 | }); 170 | 171 | //dispatch_apply:将一个指定的block执行指定的次数,常用语block数组。在一般方法中虽然block中的方法并不是顺序执行,但是由于apply是线程同步的, 172 | //所以print(dispatch_apply done);一定最后执行。常常可以这样用: 173 | let globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 174 | dispatch_async(globalQueue, { () -> Void in 175 | dispatch_apply(10, globalQueue) { (index) -> Void in 176 | print(index) 177 | } 178 | print("completed") 179 | }) 180 | print("在dispatch_apply之前") 181 | 182 | 183 | //dispatch_suspend / dispatch_resume 184 | //暂停 185 | dispatch_suspend(globalQueue) 186 | //恢复 187 | dispatch_resume(globalQueue) 188 | 189 | //Dispatch Semaphore 这个是线程的信号量,比较复杂 190 | 191 | ```` 192 | 193 | ## 参考 194 | http://liuyanwei.jumppo.com/2015/08/19/ios-ThreadAndAsynchronization.html 195 | http://blog.csdn.net/zhangao0086/article/details/38904923 196 | -------------------------------------------------------------------------------- /0_Foundation/IOS绘图.md: -------------------------------------------------------------------------------- 1 | 2 | ## Path:路径 3 | ````objc 4 | //指定当前点为 current point,Quartz会跟踪current point一般执行完一个相关函数后,current point都会相应的改变。 5 | CGContextMoveToPoint ( 6 | CGContextRef c, 7 | CGFloat x, 8 | CGFloat y 9 | ); 10 | 11 | Lines:线 12 | //从当前点 画到点,current point 会变化 13 | void CGContextAddLineToPoint ( 14 | CGContextRef c, 15 | CGFloat x, 16 | CGFloat y 17 | ); 18 | 19 | //添加多个路径 20 | void CGContextAddLines ( 21 | CGContextRef c, 22 | const CGPoint points[], 23 | size_t count 24 | ); 25 | ```` 26 | 27 | ## Arcs:弧线 28 | 29 | ````objc 30 | void CGContextAddArc ( 31 | CGContextRef c, 32 | CGFloat x, //圆心的x坐标 33 | CGFloat y, //圆心的x坐标 34 | CGFloat radius, //圆的半径 35 | CGFloat startAngle, //开始弧度 36 | CGFloat endAngle, //结束弧度 37 | int clockwise //0表示顺时针,1表示逆时针 38 | ); 39 | 40 | void CGContextAddArcToPoint( 41 | CGContextRef c, 42 | CGFloat x1, //端点1的x坐标 43 | CGFloat y1, //端点1的y坐标 44 | CGFloat x2, //端点2的x坐标 45 | CGFloat y2, //端点2的y坐标 46 | CGFloat radius //半径 47 | ); 48 | 49 | Curves 50 | 三次曲线函数 51 | void CGContextAddCurveToPoint ( 52 | CGContextRef c, 53 | CGFloat cp1x, //控制点1 x坐标 54 | CGFloat cp1y, //控制点1 y坐标 55 | CGFloat cp2x, //控制点2 x坐标 56 | CGFloat cp2y, //控制点2 y坐标 57 | CGFloat x, //直线的终点 x坐标 58 | CGFloat y //直线的终点 y坐标 59 | ); 60 | 61 | 二次曲线函数 62 | void CGContextAddQuadCurveToPoint ( 63 | CGContextRef c, 64 | CGFloat cpx, //控制点 x坐标 65 | CGFloat cpy, //控制点 y坐标 66 | CGFloat x, //直线的终点 x坐标 67 | CGFloat y //直线的终点 y坐标 68 | ); 69 | 70 | ```` 71 | 72 | 73 | ## 画椭圆,矩形 74 | 75 | ````objc 76 | void CGContextAddEllipseInRect ( 77 | CGContextRef context, 78 | CGRect rect //一矩形 79 | ); 80 | 81 | void CGContextAddRect ( 82 | CGContextRef c, 83 | CGRect rect 84 | ); 85 | 86 | ```` 87 | 88 | 89 | ## Path:路径 90 | 91 | ````objc 92 | CGContextMoveToPoint设置起点 93 | CGContextClosePath 连接起点和当前点 94 | CGPathCreateMutable 类似于 CGContextBeginPath 95 | CGPathMoveToPoint 类似于 CGContextMoveToPoint 96 | CGPathAddLineToPoint 类似于 CGContextAddLineToPoint 97 | CGPathAddCurveToPoint 类似于 CGContextAddCurveToPoint 98 | CGPathAddEllipseInRect 类似于 CGContextAddEllipseInRect 99 | CGPathAddArc 类似于 CGContextAddArc 100 | CGPathAddRect 类似于 CGContextAddRect 101 | CGPathCloseSubpath 类似于 CGContextClosePath 102 | CGContextAddPath函数把一个路径添加到graphics 103 | 104 | 路径填充和描边: 105 | Stroking :画出路径 106 | Filling :填充路径的封闭区域 107 | 108 | 路径和填充的效果 109 | 110 | //配置样式 111 | //笔触颜色 112 | CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor); 113 | //笔触宽度 114 | CGContextSetLineWidth(context, 20); 115 | //join 拐点样式 116 | // enum CGLineJoin { 117 | // kCGLineJoinMiter, //尖的,斜接 118 | // kCGLineJoinRound, //圆 119 | // kCGLineJoinBevel //斜面 120 | // }; 121 | CGContextSetLineJoin(context, kCGLineJoinRound); 122 | 123 | //Line cap 线的两端的样式 124 | // enum CGLineCap { 125 | // kCGLineCapButt, 126 | // kCGLineCapRound, 127 | // kCGLineCapSquare 128 | // }; 129 | CGContextSetLineCap(context, kCGLineCapSquare); 130 | 131 | //虚线线条样式 132 | CGFloat lengths[] = {10,10}; 133 | CGContextSetLineDash(context, 0, lengths, 2); 134 | 135 | 136 | 137 | //路径填充 138 | 139 | CGContextStrokePath(ctx); //描出路径 140 | CGContextFillPath(ctx) 使用非零绕数规则填充当前路径 141 | CGContextDrawPath 两个参数决定填充规则,kCGPathFill表示用非零绕数规则,kCGPathEOFill表示用奇偶规则,kCGPathFillStroke表示填充,kCGPathEOFillStroke表示描线,不是填充 142 | CGContextEOFillPath 使用奇偶规则填充当前路径 143 | CGContextFillRect 填充指定的矩形 144 | CGContextFillRects 填充指定的一些矩形 145 | CGContextFillEllipseInRect 填充指定矩形中的椭圆 146 | 147 | ```` 148 | 149 | ## 参考 150 | 151 | ios绘图基础 152 | http://liuyanwei.jumppo.com/2015/07/25/ios-draw-base.html 153 | 154 | 155 | ios绘图demo,做一个涂鸦板(上) 156 | http://liuyanwei.jumppo.com/2015/07/26/ios-draw-Graffiti.html 157 | 158 | ios绘图demo,做一个涂鸦板(下) 159 | http://liuyanwei.jumppo.com/2015/09/02/ios-draw-Graffiti-2.html 160 | 161 | IOS绘制圆,直线,弧线,矩形,扇形,三角形,贝塞尔等图形: 162 | http://blog.csdn.net/chocolateloveme/article/details/17246887 163 | 164 | IOS开发UI篇—Quartz2D使用(绘图路径) 165 | http://www.cnblogs.com/wendingding/p/3782679.html 166 | 167 | Paths 168 | http://donbe.blog.163.com/blog/static/138048021201052093633776/ 169 | 170 | IOS 使用Quartz 2D画虚线 171 | http://blog.csdn.net/zhangao0086/article/details/7234859 -------------------------------------------------------------------------------- /0_Foundation/JavascriptCore使用.md: -------------------------------------------------------------------------------- 1 | ````objc 2 | 3 | //直接执行js代码 4 | - (void)evaluateScript { 5 | //定义一个js并执行函数 6 | JSValue *exeFunction1 = [self.jsContext evaluateScript:@"function hi(){ return 'hi' }; hi()"]; 7 | //执行一个闭包js 8 | JSValue *exeFunction2 = [self.jsContext evaluateScript:@"(function(){ return 'hi' })()"]; 9 | 10 | //更多的应用场景使用网络或者本地文件加载一段js代码,充分利用其灵活性 11 | NSString * path = [[NSBundle mainBundle] pathForResource:@"core" ofType:@"js"]; 12 | NSString * html = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; 13 | JSValue *constructor = [self.jsContext evaluateScript:html]; 14 | 15 | } 16 | 17 | 18 | //Native注册方法给js调用 19 | - (void)regiestJSFunction { 20 | //注册一个函数 21 | [self.jsContext evaluateScript:@"var hello = function(){ return 'hello' }"]; 22 | //调用 23 | JSValue *value1 = [self.jsContext evaluateScript:@"hello()"]; 24 | 25 | //注册一个匿名函数 26 | JSValue *jsFunction = [self.jsContext evaluateScript:@" (function(){ return 'hello objc' })"]; 27 | //调用 28 | JSValue *value2 = [jsFunction callWithArguments:nil]; 29 | } 30 | 31 | //注册js方法给Native调用 32 | - (void)regiestNativeFunction { 33 | //注册一个objc方法给js调用 34 | self.jsContext[@"log"] = ^(NSString *msg){ 35 | NSLog(@"js:msg:%@",msg); 36 | }; 37 | //另一种方式,利用currentArguments获取参数 38 | self.jsContext[@"log"] = ^() { 39 | NSArray *args = [JSContext currentArguments]; 40 | for (id obj in args) { NSLog(@"%@",obj); } 41 | }; 42 | //使用js调用objc 43 | [self.jsContext evaluateScript:@"native_log('hello,i am js side')"]; 44 | } 45 | 46 | //注册js错误处理 47 | - (void)jsExceptionHandler { 48 | self.jsContext.exceptionHandler = ^(JSContext *con, JSValue *exception) { 49 | NSLog(@"%@", exception); 50 | con.exception = exception; 51 | }; 52 | } 53 | 54 | //JSExprot协议使用 55 | - (void)useJSExprot { 56 | Person *p = [[Person alloc]init]; 57 | self.jsContext[@"person"] = p; 58 | 59 | JSValue *value = [self.jsContext evaluateScript:@"person.whatYouName()"]; 60 | 61 | } 62 | 63 | ```` 64 | 65 | Person.h 66 | 67 | ````objc 68 | 69 | #import 70 | #import 71 | 72 | 73 | @protocol JSPersonProtocol 74 | 75 | @property (nonatomic, copy) NSDictionary *data; 76 | - (NSString *)whatYouName; 77 | 78 | @end 79 | 80 | 81 | @interface Person : NSObject 82 | 83 | @property (nonatomic, copy)NSString *name; 84 | - (NSString *)whatYouName; 85 | 86 | @end 87 | 88 | 89 | ```` 90 | 91 | Person.m 92 | 93 | ````objc 94 | #import "Person.h" 95 | 96 | @implementation Person 97 | 98 | -(NSString *)whatYouName { 99 | return @"hi"; 100 | } 101 | 102 | 103 | @end 104 | 105 | 106 | ```` 107 | 108 | //http://blog.iderzheng.com/ios7-objects-management-in-javascriptcore-framework/ 109 | //http://www.webryan.net/2013/10/about-ios7-javascriptcore-framework/ 110 | 111 | -------------------------------------------------------------------------------- /0_Foundation/NSBundle获取不到文件路径.md: -------------------------------------------------------------------------------- 1 | # NSBundle获取不到文件路径 2 | 3 | 获取项目资源的方法:例如获取工程中的 1.txt 4 | [[NSBundle mainBundle] pathForResource:@"1" ofType:@"txt"]; 5 | [[NSBundle mainBundle] pathForResource:@"1.txt" ofType:nil]; 6 | 7 | 8 | 但是获取一个不常见的文件扩展名,例如enc,通过这个方式有时候获取不到,原因是你拖拽文件进入工程时,不常见的扩展名文件不会自动加入到Copy Bundle Resource中,需要手动添加一次,之后在使用方法就可以获取到了。 9 | -------------------------------------------------------------------------------- /0_Foundation/NSJSONReadingOptions类型说明.md: -------------------------------------------------------------------------------- 1 | ````objc 2 | NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; 3 | ```` 4 | 5 | ## 解析json时的options有三种选项 6 | ````objc 7 | typedef NS_OPTIONS(NSUInteger, NSJSONReadingOptions) { 8 | NSJSONReadingMutableContainers = (1UL << 0), 9 | NSJSONReadingMutableLeaves = (1UL << 1), 10 | NSJSONReadingAllowFragments = (1UL << 2) 11 | } NS_ENUM_AVAILABLE(10_7, 5_0); 12 | 13 | ```` 14 | 15 | ````objc 16 | SJSONReadingMutableContainers:返回可变容器,NSMutableDictionary或NSMutableArray。 17 | 18 | NSJSONReadingMutableLeaves:返回的JSON对象中字符串的值为NSMutableString,目前在iOS 7上测试不好用,应该是个bug,参见: 19 | http://stackoverflow.com/questions/19345864/nsjsonreadingmutableleaves-option-is-not-working 20 | 21 | NSJSONReadingAllowFragments:允许JSON字符串最外层既不是NSArray也不是NSDictionary,但必须是有效的JSON Fragment。例如使用这个选项可以解析 @“123” 这样的字符串。参见: 22 | http://stackoverflow.com/questions/16961025/nsjsonserialization-nsjsonreadingallowfragments-reading 23 | 24 | ```` 25 | -------------------------------------------------------------------------------- /0_Foundation/NSLog的格式.md: -------------------------------------------------------------------------------- 1 | NSLog的格式如下所示: 2 | 3 | ````objc 4 | 5 | %@ 对象 6 | %i 整数 7 | %d, double 8 | %u 无符整形 9 | %f 浮点/双字 10 | %x, %X 二进制整数 11 | %o 八进制整数 12 | %zu size_t 13 | %p 指针 14 | %e 浮点/双字 (科学计算) 15 | %g 浮点/双字 16 | %s short 17 | %.*s Pascal字符串 18 | %c 字符 char 19 | %C unichar 20 | %lld 64位长整数(long long) 21 | %llu 无符64位长整数 22 | %Lf 64位双字 23 | %zu size_t 24 | 25 | %# A class object (Class) 26 | %: A method selector (SEL) 27 | 28 | 29 | ```` 30 | 31 | 打印百分号: ````%%```` 32 | 33 | - [参考链接](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100-SW1) -------------------------------------------------------------------------------- /0_Foundation/NSString常用方法.md: -------------------------------------------------------------------------------- 1 | ````objc 2 | //创建一个NSString 3 | NSString *myString1 = @"some string"; 4 | 5 | //格式化创建 6 | NSString *myString2 = [NSString stringWithFormat:@"%@",myString1]; 7 | 8 | //返回数字的值 9 | NSString *myString3 = @"123"; 10 | double doubleString = [myString3 floatValue]; 11 | int intString = [myString3 intValue]; 12 | 13 | //比较两个字符串,若相同返回TURE 14 | BOOL areEqual = [myString1 isEqualToString:myString2]; 15 | 16 | //区分大小写的比较 17 | BOOL areEqual1 = ([myString1 caseInsensitiveCompare:myString2] == NSOrderedSame); 18 | 19 | 20 | //转换大小写 21 | NSString *myString4 = @"asdfg"; 22 | NSString *upper = [myString4 uppercaseString]; 23 | NSString *lower = [upper lowercaseString]; 24 | 25 | //截去字符串(以空格为例) 26 | //whitespaceAndNewlineCharacterSet去除前后的空格和换行符 27 | //whitespaceCharacterSet 去除前后的空格,实际效果来看只实现了去除首字母前面的空格 28 | NSString *myString5 = @" one two three "; 29 | NSString *trimmed1 = [myString5 stringByTrimmingCharactersInSet:[NSCharacterSetwhitespaceAndNewlineCharacterSet]]; 30 | NSString *trimmed2 = [myString5 stringByTrimmingCharactersInSet:[NSCharacterSetwhitespaceCharacterSet]]; 31 | 32 | 33 | 34 | //predicate 断言断定,使基于,下面的方法实现删除空格 35 | NSPredicate *noE = [NSPredicatepredicateWithFormat:@"SELF!=''"]; 36 | NSArray *part = [myString5 componentsSeparatedByCharactersInSet:[NSCharacterSetwhitespaceCharacterSet]]; 37 | NSArray *file = [part filteredArrayUsingPredicate:noE]; 38 | NSString *trimmed3 = [file componentsJoinedByString:@""]; 39 | NSLog(@"trimmed3 = %@",trimmed3); 40 | 41 | //有已知字符串创建子字符串 42 | NSString * number = @"abx cdefghi gklmn"; 43 | //substringToIndex获取字符串的前三个 44 | //substringFromIndex从第三个开始截取到最后 45 | NSString *myString6 = [number substringToIndex:3]; 46 | 47 | //用边界截取起始位置为第四个,长度为5个长度 48 | NSRange range = NSMakeRange(4, 5); 49 | NSString *aString = [number substringWithRange:range]; 50 | 51 | 52 | //创建成数组 53 | NSArray *arr = [number componentsSeparatedByString:@" "]; 54 | 55 | //替换子字符串 56 | NSString *myString7 = [number stringByReplacingOccurrencesOfString:@"efg"withString:@"aaa"]; 57 | 58 | //查找子字符串,这段代码返回(4,3); 59 | NSRange found = [number rangeOfString:@"cde"]; 60 | 61 | //判读那是否包含 62 | BOOL found1 = ([number rangeOfString:@"cde"].location !=NSNotFound); 63 | 64 | //组合字符串 65 | NSString *myString9 = [myString1 stringByAppendingString:myString7]; 66 | NSString *myString10 = [myString1 stringByAppendingFormat:myString7]; 67 | 68 | //将文件内容写入到字符串中 69 | NSString *fileContents = [NSString stringWithContentsOfFile:@"123.text"]; 70 | 71 | //获取文件扩展名 72 | NSString *filename = @"11111.txt"; 73 | NSString *fileExtension = [filename pathExtension]; 74 | 75 | //将URL内容写入字符串 76 | NSURL *url = [NSURLURLWithString:@"http://www.baidu.com"]; 77 | NSString *pageContents = [NSString stringWithContentsOfURL:url]; 78 | 79 | ```` -------------------------------------------------------------------------------- /0_Foundation/Notification和KVO.md: -------------------------------------------------------------------------------- 1 | 2 | ## Notification 3 | 4 | ````objc 5 | //1:注册监听 6 | //订阅NSNotificationCenter 7 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification:) name:@"test" object:nil]; 8 | 9 | //2:监听事件 10 | - (void)receiveNotification:(id)sender { 11 | NSLog(@"receive msg is:%@",sender); 12 | } 13 | 14 | //3:发送notification 15 | [[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:self.testString]; 16 | 17 | ```` 18 | 19 | ## KVO 20 | 21 | 22 | objc 23 | 24 | ````objc 25 | 26 | //1:设置监听对象 27 | //@property(nonatomic,strong) NSString *testString; 28 | [self addObserver:self forKeyPath:@"testString" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"testString has changed"]; 29 | 30 | //2:注册监听 31 | //当发起监听的对象的对应keypath改变时,即引起事件 !!!!!注意:使用_testString的方法不起作用!!!!!!! 32 | self.testString = @"hello observe !!!"; 33 | 34 | //3:注册监听委托方法 35 | -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ 36 | NSLog(@"%@",context); 37 | } 38 | 39 | ```` 40 | 41 | swift 42 | 43 | ````swift 44 | 45 | //监听是否可以前进后退,修改btn.enable属性 46 | webView.addObserver(self, forKeyPath: "loading", options: .New, context: nil) 47 | //监听加载进度 48 | webView.addObserver(self, forKeyPath: "estimatedProgress", options: .New, context: nil) 49 | 50 | //重写self的kvo方法 51 | override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer) { 52 | if (keyPath == "loading") { 53 | gobackBtn.enabled = webView.canGoBack 54 | forwardBtn.enabled = webView.canGoForward 55 | } 56 | if (keyPath == "estimatedProgress") { 57 | //progress是UIProgressView 58 | progress.hidden = webView.estimatedProgress==1 59 | progress.setProgress(Float(webView.estimatedProgress), animated: true) 60 | } 61 | } 62 | 63 | ```` 64 | -------------------------------------------------------------------------------- /0_Foundation/Objectc 中__attribute__的用法.md: -------------------------------------------------------------------------------- 1 | ## Objectc 中__attribute__的用法: 2 | 3 | __attribute是gcc中的功能,c常用,object也可以使用。 4 | 5 | 6 | ### 1:申明方法是一个弃用的方法 7 | 8 | ````objc 9 | __attribute__ ((deprecated)) 10 | 11 | 例如: 12 | +(void)plantList:(NSString *)userId __attribute__ ((deprecated)); 13 | 14 | ```` 15 | 16 | 17 | ### 2: 声明反函数无返回值 18 | 19 | __attribute__ ((noreturn) 20 | 21 | ````objc 22 | 23 | 例子: 24 | 在.h文件中申明函数:+(int)test:(NSString *)userId ;那么在.m中实现这个函数必须要返回一个int,否则编译器会报错, 25 | 若给函数加上__attribute__ ((deprecated)),则编译器会通过编译,但是有个条警告。 26 | 27 | ```` 28 | 29 | 30 | ### 3:让方法在构造函数先,或后执行 31 | 32 | ````objc 33 | 34 | 写法1:__attribute__((constructor)) 35 | 写法2:__attribute__((constructor(优先级数字))) :注意,优先级数字要大于100,0-100是系统保留的。 36 | 写法3:先定义一个,满足声明的函数,然后在定义函数 37 | void main_prv(void) __attribute__((constructor)); 38 | 39 | void main_prv(void) 40 | { 41 | printf(" main_prv!"); 42 | } 43 | 44 | 45 | 例子,在main.m文件中,代码会在main函数之前先执行before101(),before102(),before103(),before(),并且在main函数执行后执行 after() 46 | 47 | int main(int argc, char * argv[]) { 48 | @autoreleasepool { 49 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 50 | } 51 | } 52 | 53 | static __attribute__((constructor)) void before() 54 | { 55 | 56 | printf("before"); 57 | } 58 | 59 | static __attribute__((destructor)) void after() 60 | { 61 | printf(" after!\n"); 62 | } 63 | 64 | static __attribute__((constructor(101))) void before101() 65 | { 66 | printf(" before! 101"); 67 | } 68 | 69 | static __attribute__((constructor(102))) void before102() 70 | { 71 | printf(" before! 102"); 72 | } 73 | 74 | static __attribute__((constructor(103))) void before103() 75 | { 76 | printf(" before! 103"); 77 | } 78 | 79 | 80 | ```` 81 | 82 | 83 | ### 4:还有很多更多的功能 84 | 85 | [更多工具](http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Type-Attributes.html) 86 | -------------------------------------------------------------------------------- /0_Foundation/Swizzling.md: -------------------------------------------------------------------------------- 1 | ## Swizzling 2 | > Swizzling用一个词解释就是偷天换日。通过重新映射方法代替原有的方法 3 | 4 | 5 | 举例:使用xxx_viewWillAppear方法替代原先的viewWillAppear方法 6 | 7 | ````objc 8 | + (void)load { 9 | static dispatch_once_t onceToken; 10 | dispatch_once(&onceToken, ^{ 11 | Class class = [self class]; 12 | // When swizzling a class method, use the following: 13 | // Class class = object_getClass((id)self); 14 | 15 | SEL originalSelector = @selector(viewWillAppear:); 16 | SEL swizzledSelector = @selector(xxx_viewWillAppear:); 17 | 18 | Method originalMethod = class_getInstanceMethod(class, originalSelector); 19 | Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); 20 | 21 | BOOL didAddMethod = 22 | class_addMethod(class, 23 | originalSelector, 24 | method_getImplementation(swizzledMethod), 25 | method_getTypeEncoding(swizzledMethod)); 26 | 27 | if (didAddMethod) { 28 | class_replaceMethod(class, 29 | swizzledSelector, 30 | method_getImplementation(originalMethod), 31 | method_getTypeEncoding(originalMethod)); 32 | } else { 33 | method_exchangeImplementations(originalMethod, swizzledMethod); 34 | } 35 | }); 36 | } 37 | 38 | #pragma mark - Method Swizzling 39 | 40 | - (void)xxx_viewWillAppear:(BOOL)animated { 41 | [self xxx_viewWillAppear:animated]; 42 | NSLog(@"viewWillAppear: %@", self); 43 | } 44 | ```` 45 | 46 | ## 注意 47 | 48 | - Swizzling应该总是在+load中执行 49 | - Swizzling应该总是在dispatch_once中执行 50 | - 51 | -------------------------------------------------------------------------------- /0_Foundation/URL编码.md: -------------------------------------------------------------------------------- 1 | 2 | ````objc 3 | 4 | //原始地址 5 | NSString *urlString = @"http://wwW.xxx.com?query= this is question"; 6 | 7 | //url编码 8 | [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]//ios 9+ 9 | [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]//ios9 - 10 | 11 | //去除url编码 12 | urlEncodeString = [urlEncodeString stringByRemovingPercentEncoding]; 13 | 14 | ```` 15 | 16 | -------------------------------------------------------------------------------- /0_Foundation/USURL用法.md: -------------------------------------------------------------------------------- 1 | 2 | ## 0.经典用法 3 | ````objc 4 | NSURL *url1 = [NSURL URLWithString:@"http://www.baidu.com/img/bd_logo1.png"]; 5 | NSURL *url2 = [NSURL URLWithString:@"/img/bd_logo1.png" relativeToURL:[NSURL URLWithString:@"http://www.baidu.com"]]; 6 | ```` 7 | ## 1.加载项目中本地网页 8 | ````objc 9 | NSString *urlPath = [[NSBundle mainBundle] pathForResource:@"404" ofType:@"html"]; 10 | NSURL *url = [NSURL URLWithString:urlPath]; 11 | ```` 12 | ## 2.获取扩展名 13 | ````objc 14 | NSURL *url = [NSURL URLWithString:@"http://www.iyiming.me/hello.png"]; 15 | NSString *pathExtension = [url pathExtension];//扩展名 png 16 | ```` 17 | ## 3.获取组成部分 18 | ````objc 19 | NSURL *url = [NSURL URLWithString:@"http://www.iyiming.me/index.htm"]; 20 | NSArray *pathComponentsArray = [url pathComponents];//所有组成部分 [/,index.htm] 21 | ```` 22 | ## 4.获取主机 23 | ````objc 24 | NSURL *url = [NSURL URLWithString:@"http://www.iyiming.me/index.htm"]; 25 | NSString *host = [url host];//主机 www.iyiming.me 26 | ```` 27 | ## 5.获取端口号 28 | ````objc 29 | NSURL *url = [NSURL URLWithString:@"http://www.iyiming.me:80/index.htm"]; 30 | NSNumber *port = [url port];//端口号 80 31 | ```` 32 | ## 6.获取查询参数 33 | ````objc 34 | NSURL *url = [NSURL URLWithString:@"http://www.iyiming.me:80/index.htm?key1=value1&key2=value2"]; 35 | NSString *query = [url query];//查询参数 key1=value1&key2=value2 36 | ```` 37 | ## 7.获取协议名称 38 | ````objc 39 | NSURL *url = [NSURL URLWithString:@"http://www.iyiming.me:80/index.htm?key1=value1&key2=value2"]; 40 | NSString *scheme = [url scheme];//协议 http 41 | ```` 42 | ## 8.获取锚定位 43 | ````objc 44 | NSURL *url = [NSURL URLWithString:@"http://www.iyiming.me:80/index.htm#jumpLocation"]; 45 | NSString *fragment = [url fragment];//锚定位 jumpLocation 46 | ```` 47 | ## 9.获取用户名 48 | ````objc 49 | NSURL *url = [NSURL URLWithString:@"ftp://yiming@www.iyiming.me"]; 50 | NSString *user = [url user];//用户名 yiming 51 | ```` 52 | -------------------------------------------------------------------------------- /0_Foundation/cookie操作.md: -------------------------------------------------------------------------------- 1 | ## 获取服务端cookie 2 | 3 | ````objc 4 | //获取cookie 5 | NSDictionary *headers = [((NSHTTPURLResponse *)resp) allHeaderFields]; 6 | NSLog(@"headers:%@",headers); 7 | NSDictionary *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:headers forURL:[NSURL URLWithString:@"http://localhost/"]]; 8 | 9 | for (NSHTTPCookie *cookie in cookies) { 10 | NSLog(@"cookie:%@",cookie); 11 | if ([[cookie name] isEqualToString:@"JSESSIONID"]) { 12 | NSLog(@"session id is %@",[cookie value]); 13 | } 14 | } 15 | ```` 16 | ## 获取客户端cookie 17 | 18 | ````objc 19 | //获取本地cookie 20 | NSHTTPCookieStorage *httpCookiesStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; 21 | NSDictionary *cookies = [httpCookiesStorage cookiesForURL:[NSURL URLWithString:@"http://localhost/"]]; 22 | for (NSHTTPCookie *cookie in cookies) { 23 | NSLog(@"cookie:%@",cookie); 24 | } 25 | 26 | ```` 27 | 28 | ## 客户端设置cookie 29 | 30 | ````objc 31 | //客户端设置cookie 32 | -(void)clientSetCookie{ 33 | 34 | NSDictionary *prop1 = [NSDictionary dictionaryWithObjectsAndKeys: 35 | @"a",NSHTTPCookieName, 36 | @"aaa",NSHTTPCookieValue, 37 | @"/",NSHTTPCookiePath, 38 | [NSURL URLWithString:@"http://localhost/"],NSHTTPCookieOriginURL, 39 | [NSDate dateWithTimeIntervalSinceNow:60],NSHTTPCookieExpires, 40 | nil]; 41 | NSDictionary *prop2 = [NSDictionary dictionaryWithObjectsAndKeys: 42 | @"b",NSHTTPCookieName, 43 | @"bbb",NSHTTPCookieValue, 44 | @"/",NSHTTPCookiePath, 45 | [NSURL URLWithString:@"http://localhost/"],NSHTTPCookieOriginURL, 46 | [NSDate dateWithTimeIntervalSinceNow:60],NSHTTPCookieExpires, 47 | nil]; 48 | 49 | NSHTTPCookie *cookie1 = [NSHTTPCookie cookieWithProperties:prop1]; 50 | NSHTTPCookie *cookie2 = [NSHTTPCookie cookieWithProperties:prop2]; 51 | 52 | //单个设置 53 | [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie1]; 54 | [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie2]; 55 | 56 | //批量设置 57 | // NSArray *cookies = @[cookie1,cookie2,cookie3]; 58 | // [[NSHTTPCookieStorage sharedHTTPCookieStorage]setCookies:cookies forURL:[NSURL URLWithString:@"http://localhost/"] mainDocumentURL:nil]; 59 | 60 | //设置cookie本地缓存策略 61 | //NSHTTPCookieAcceptPolicyAlways:保存所有cookie,这个是默认值 62 | //NSHTTPCookieAcceptPolicyNever:不保存任何响应头中的cookie 63 | //NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:只保存域请求匹配的cookie 64 | 65 | [[NSHTTPCookieStorage sharedHTTPCookieStorage]setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; 66 | 67 | NSLog(@"设置完成"); 68 | } 69 | 70 | 71 | ```` 72 | 73 | ## 删除cookie 74 | 75 | ````objc 76 | 77 | #pragma mark -客户端删除cookie 78 | //根据url和name删除cookie 79 | -(void)deleteCookie:(NSString *)cookieName url:(NSURL *)url{ 80 | //根据url找到所属的cookie集合 81 | NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage]cookiesForURL:url]; 82 | for (NSHTTPCookie *cookie in cookies) { 83 | if([cookie.name isEqualToString:cookieName]){ 84 | [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie]; 85 | NSLog(@"删除cookie:%@",cookieName); 86 | } 87 | } 88 | } 89 | //删除全部cookies 90 | -(void)deleteCookies{ 91 | for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage]cookies]) { 92 | [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie]; 93 | } 94 | NSLog(@"删除完成"); 95 | } 96 | ```` 97 | 98 | ## cookie策略 99 | 100 | 101 | ````objc 102 | //设置cookie本地缓存策略 103 | //NSHTTPCookieAcceptPolicyAlways:保存所有cookie,这个是默认值 104 | //NSHTTPCookieAcceptPolicyNever:不保存任何响应头中的cookie 105 | //NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:只保存域请求匹配的cookie 106 | ```` -------------------------------------------------------------------------------- /0_Foundation/https请求处理-信任一切证书.md: -------------------------------------------------------------------------------- 1 | ios https请求处理方式1:信任一切证书 2 | 3 | ## 处理方法 4 | 5 | ### 1:使用异步请求方式 6 | 7 | ### 2:证书信任的委托这样处理 8 | 9 | ````objc 10 | -(BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection{ 11 | return true; 12 | } 13 | - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{ 14 | NSLog(@"didReceiveAuthenticationChallenge %@ %zd", [[challenge protectionSpace] authenticationMethod], (ssize_t) [challenge previousFailureCount]); 15 | if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){ 16 | [[challenge sender] useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 17 | [[challenge sender] continueWithoutCredentialForAuthenticationChallenge: challenge]; 18 | } 19 | } 20 | 21 | - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace{ 22 | return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]; 23 | } 24 | ```` 25 | 26 | ## 完整示例代码 27 | 28 | UIViewController.h 29 | 30 | ````objc 31 | 32 | #import 33 | 34 | @interface ViewController : UIViewController 35 | 36 | @end 37 | ```` 38 | 39 | UIViewController.m 40 | 41 | 42 | ````objc 43 | 44 | #import "ViewController.h" 45 | 46 | @interface ViewController () 47 | 48 | @end 49 | 50 | @implementation ViewController 51 | 52 | - (void)viewDidLoad { 53 | [super viewDidLoad]; 54 | 55 | //string 转 url编码 56 | NSString *urlString = @"https://api.github.com/users/coolnameismy"; 57 | NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]]; 58 | 59 | 60 | NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; 61 | NSURLConnectionDataDelegate *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; 62 | 63 | [connection start]; 64 | } 65 | 66 | //请求失败 67 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ 68 | NSLog(@"=================didFailWithError================="); 69 | NSLog(@"error:%@",error); 70 | } 71 | 72 | //重定向 73 | - (nullable NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(nullable NSURLResponse *)response{ 74 | NSLog(@"=================request redirectResponse================="); 75 | NSLog(@"request:%@",request); 76 | return request; 77 | } 78 | 79 | //接收响应 80 | - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ 81 | NSLog(@"=================didReceiveResponse================="); 82 | NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response; 83 | NSLog(@"response:%@",resp); 84 | } 85 | 86 | //接收响应 87 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ 88 | NSLog(@"=================didReceiveData================="); 89 | NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; 90 | NSLog(@"data:%@",dic); 91 | } 92 | 93 | //- (nullable NSInputStream *)connection:(NSURLConnection *)connection needNewBodyStream:(NSURLRequest *)request{ 94 | // 95 | //} 96 | 97 | //上传数据委托,用于显示上传进度 98 | - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten 99 | totalBytesWritten:(NSInteger)totalBytesWritten 100 | totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite{ 101 | NSLog(@"=================totalBytesWritten================="); 102 | } 103 | 104 | //- (nullable NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse{ 105 | // 106 | //} 107 | 108 | //完成请求 109 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection{ 110 | NSLog(@"=================connectionDidFinishLoading================="); 111 | } 112 | 113 | 114 | #pragma mark -https认证 115 | -(BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection{ 116 | return true; 117 | } 118 | - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{ 119 | NSLog(@"didReceiveAuthenticationChallenge %@ %zd", [[challenge protectionSpace] authenticationMethod], (ssize_t) [challenge previousFailureCount]); 120 | if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){ 121 | [[challenge sender] useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 122 | [[challenge sender] continueWithoutCredentialForAuthenticationChallenge: challenge]; 123 | } 124 | } 125 | 126 | - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace{ 127 | return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]; 128 | } 129 | 130 | - (void)didReceiveMemoryWarning { 131 | [super didReceiveMemoryWarning]; 132 | // Dispose of any resources that can be recreated. 133 | } 134 | 135 | @end 136 | 137 | 138 | ```` 139 | 140 | 141 | ## 参考文章 142 | 143 | -[iOS: HTTPS 与自签名证书](http://blog.csdn.net/kmyhy/article/details/7733619) 144 | -[iOS - HTTPS](http://www.jianshu.com/p/4b5d2d47833d) 145 | -[iOS安全系列之一:HTTPS](http://oncenote.com/2014/10/21/Security-1-HTTPS/) 146 | -[iOS安全系列之二:HTTPS进阶](http://oncenote.com/2015/09/16/Security-2-HTTPS2/) 147 | -[Making HTTP and HTTPS Requests](https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/WorkingWithHTTPAndHTTPSRequests/WorkingWithHTTPAndHTTPSRequests.html) 148 | -------------------------------------------------------------------------------- /0_Foundation/ios9支持http请求.md: -------------------------------------------------------------------------------- 1 | ##ios9 回退不安全网络模式(支持http协议) 2 | 3 | 在项目中找到info.plist 源文件形式打开,添加下面内容 4 | 5 | ```` 6 | NSAppTransportSecurity 7 | 8 | NSAllowsArbitraryLoads 9 | 10 | 11 | ```` 12 | 13 | -------------------------------------------------------------------------------- /0_Foundation/ios中bundle的使用.md: -------------------------------------------------------------------------------- 1 | ## ios中bundle的使用 2 | 3 | 将图片文件夹的后缀改名为:xxx.bundle 4 | 5 | ## VC获得bundle中的资源 6 | 7 | NSString * bundlePath = [[ NSBundle mainBundle] pathForResource: @ "MyBundle" ofType :@ "bundle"]; 8 | NSBundle *resourceBundle = [NSBundle bundleWithPath:bundlePath]; 9 | UIViewController *vc = [[UIViewController alloc] initWithNibName:@"vc_name" bundle:resourceBundle]; 10 | 11 | ## UIImageView获得bundle中的资源 12 | 13 | UIImageView *imgView=[[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)]; 14 | UIImage *image = [UIImage imageNamed:@"MyBundle.bundle/img_collect_success"]; 15 | [imgView setImage:image]; 16 | 17 | -------------------------------------------------------------------------------- /0_Foundation/ios开发的系统兼容性问题解决.md: -------------------------------------------------------------------------------- 1 | ## ios开发的系统兼容性问题解决 2 | 3 | ### 1:系统方法过时的注解 4 | 5 | ````objc 6 | 7 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo NS_DEPRECATED_IOS(2_0, 3_0); 8 | 9 | 10 | 说明方法在2.0时代引入,3.0时代过时 11 | 12 | ```` 13 | 14 | ## 2:系统不同版本方法的兼容性解决方案1 (最佳,不产生警告) 15 | 16 | ````objc 17 | 18 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 19 | if([picker respondsToSelector:@selector(dismissModalViewControllerAnimated:)]){ 20 | [picker dismissModalViewControllerAnimated:YES completion:nil]; 21 | } 22 | #else{ 23 | [picker dismissViewControllerAnimated:YES completion:nil]; 24 | } 25 | #endif 26 | 27 | ```` 28 | 29 | ## 3:系统不同版本方法的兼容性解决方案2:(书写方便,但是会产生警告) 30 | 31 | ````objc 32 | 33 | if([picker respondsToSelector:@selector(imagePickerController:didFinishPickingMediaWithInfo:)]){ 34 | [picker dismissViewControllerAnimated:YES completion:nil]; 35 | }else{ 36 | [picker dismissModalViewControllerAnimated:YES]; 37 | } 38 | 39 | ```` 40 | 41 | ## 4: 获取系统版本号进行判断 (书写方便,但是会产生警告) 42 | 43 | ````objc 44 | if ([[[UIDevice currentDevice]systemVersion] floatValue] >= 9) { 45 | if (!self.centralManager.isScanning) { 46 | [self.centralManager scanForPeripheralsWithServices:nil options:nil]; 47 | } 48 | } else { 49 | [self.centralManager scanForPeripheralsWithServices:nil options:nil]; 50 | } 51 | ```` -------------------------------------------------------------------------------- /0_Foundation/json对象处理.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## json 转 NSObject 和 NSObject转json 4 | 5 | ````objc 6 | //1:对象需要实现NSCoding协议 7 | - (void)encodeWithCoder:(NSCoder *)aCoder{ 8 | 9 | [aCoder encodeObject:self.uid forKey:@"uid"]; 10 | [aCoder encodeObject:self.pwd forKey:@"pwd"]; 11 | [aCoder encodeObject:self.headerPortaitUrl forKey:@"headerPortaitUrl"]; 12 | } 13 | - (id)initWithCoder:(NSCoder *)aDecoder{ 14 | 15 | self.uid = [aDecoder decodeObjectForKey:@"uid"]; 16 | self.pwd = [aDecoder decodeObjectForKey:@"pwd"]; 17 | self.headerPortaitUrl = [aDecoder decodeObjectForKey:@"headerPortaitUrl"]; 18 | return self; 19 | } 20 | 21 | //2:转json和转object 22 | NSData *data= [NSKeyedArchiver archivedDataWithRootObject:[UserInfo sharedUserInfo]]; 23 | [[self userDefaults] setObject:data forKey:@"userinfo"]; 24 | [[self userDefaults] synchronize]; 25 | 26 | NSData *cacheData = [[NSUserDefaults standardUserDefaults] objectForKey:@"userinfo" ]; 27 | UserInfo *cacheUserinfo= [NSKeyedUnarchiver unarchiveObjectWithData:cacheData]; 28 | 29 | ```` 30 | 31 | ## json 转 NSArray 和 NSDictionary 32 | 33 | ````objc 34 | 35 | var json1="{\"中国\":{ \"北京\":{\"北京1\":1,\"北京2\":2,\"北京3\":3}, \"上海\":{\"上海1\":4,\"上海2\":5,\"上海3\":6},\"广州\":{\"广州1\":7,\"广州2\":8,\"广州3\":9}}}"; 36 | var json2="[{\"test\":\"1\"},{\"test2\":\"2\"}]"; 37 | 38 | var data1 = json1.dataUsingEncoding(NSUTF8StringEncoding); 39 | var data2 = json2.dataUsingEncoding(NSUTF8StringEncoding); 40 | 41 | var obj1:NSDictionary = NSJSONSerialization.JSONObjectWithData(data1!, options: NSJSONReadingOptions.allZeros, error: nil) as NSDictionary 42 | var obj2:NSArray = NSJSONSerialization.JSONObjectWithData(data2!, options: NSJSONReadingOptions.allZeros, error: nil) 43 | as NSArray 44 | 45 | // 46 | for (key,value) in obj1{ 47 | println("\(key)\(value)"); 48 | } 49 | for item in obj2{ 50 | println("\(item)"); 51 | } 52 | 53 | obj2.firstObject?.objectForKey("test") 54 | 55 | ```` 56 | 57 | ## NSArray NSDictionary 转 NSString 58 | 59 | ````objc 60 | var re_jsonData1 = NSJSONSerialization.dataWithJSONObject(obj1, options: NSJSONWritingOptions.allZeros, error: nil); 61 | 62 | var re_json1 = NSString(data: re_jsonData1!, encoding: NSUTF8StringEncoding); 63 | 64 | var re_jsonData2 = NSJSONSerialization.dataWithJSONObject(obj2, options: NSJSONWritingOptions.allZeros, error: nil); 65 | 66 | var re_json2 = NSString(data: re_jsonData2! , encoding: NSUTF8StringEncoding) 67 | 68 | ```` -------------------------------------------------------------------------------- /0_Foundation/objc 验证参数有效性的方法.md: -------------------------------------------------------------------------------- 1 | ## objc 验证参数有效性的方法 2 | 3 | 使用NSParameterAssert 可以做参数有限性验证,如果错误则抛出异常,例如: 4 | 5 | ````objc 6 | NSParameterAssert([dictionary isKindOfClass:NSDictionary.class]); 7 | ```` 8 | 9 | -------------------------------------------------------------------------------- /0_Foundation/objc二进制数据处理.md: -------------------------------------------------------------------------------- 1 | ## 常见的二进制类型 2 | 3 | typedef uint8_t BYTE; 4 | typedef uint32_t DWORD; 5 | typedef int32_t LONG; 6 | typedef uint16_t WORD; 7 | 8 | 9 | int8_t flag = 0b10000000; 10 | int8_t flag1 = (flag & 0b01111111) | 0b00000011; 11 | 12 | 变量结果: 13 | flag int8_t '\x80' 14 | flag1 int8_t '\x03' 15 | 16 | 1、2月15提供第一个版本,该版本包含蓝牙广播、服务定义,传输数据拆包,组包以及导出给用户的API 17 | 2、2月底 SDK增加据安全部分代码 18 | 3、三月底实现OTA 19 | 20 | ## 数据转换 21 | 22 | //uint8_t转换到NSUInteger 23 | NSUInteger i = (NSInteger)length; 24 | 25 | //byte->NSInteger 26 | Byte b = 123; 27 | NSInteger x; 28 | x = b; 29 | 30 | 31 | ## 数据操作 32 | > 数据操作主要分为三种类型,分别是字节流操作(NSData) 字节操作(Byte) 位操作(bit) 33 | 34 | 1:直接用byte数组或byte写,例如: 35 | byte buffer = {0x1e,0x07,0x01,0x01,0x02,0x03}; 36 | byte day = {0x01}; 37 | 38 | 2:使用NSMutableData写数据 39 | NSMutableData *temp = [[NSMutableData alloc]init]; 40 | Byte a1[] = {0x1e,0x07}; 41 | Byte a2 = 0x01; 42 | Byte a3 = 0x01; 43 | Byte a4 = 0x02; 44 | Byte a5 = 0x03; 45 | [temp appendBytes:&a1 length:2]; 46 | [temp appendBytes:&a2 length:1]; 47 | [temp appendBytes:&a3 length:1]; 48 | [temp appendBytes:&a4 length:1]; 49 | [temp appendBytes:&a5 length:1]; 50 | //结果: <1e070101 0203> 51 | 52 | 3:写byte 53 | 54 | 55 | 56 | 4:data数据操作 57 | 58 | 比较: [data isEqualToData:actualData] 59 | 写入: [data appendBytes:&a1 length:2]; 60 | 截取: [data subdataWithRange:NSMakeRange(200, 500)]; 61 | 前排插入byte的黑科技~:[data replaceBytesInRange:NSMakeRange(0, 0) withBytes:&byte length:2]; 62 | 63 | 5:crc校验 64 | 65 | #import //需要导入libz.tbd 66 | 67 | NSData *data; 68 | 69 | // ... 70 | 71 | unsigned long result = crc32(0, data.bytes, data.length); 72 | NSLog(@"CRC32: %lu", result); 73 | 74 | 75 | ## bit操作 76 | 77 | 假设flag是一个byte位的数据,` int8_t flag = 0b00000000; ` 78 | 79 | - 获取bit位数据 80 | 81 | `uint8_t encrypt = (flag & 0b00010000) >> 4; ` 82 | 83 | 说明:先用&操作去除其他flag其他无用的bit位,只保留第bit5位置,然后在右移动四位,转成int,得到结果就是0或1 84 | 85 | - bit位赋值 86 | 87 | 例如给flag的第4个bit位赋值,可以使用位与运算, flag = flag | 0b00010000; 88 | 89 | 90 | ### 例子: 91 | 92 | ```` 93 | Byte flag = [ALUntil composeFlagWithID:14 preset:YES complex:YES encrypt:YES]; 94 | uint8_t msgID = flag & 0b00001111; 95 | //encrypt 96 | uint8_t encrypt = (flag & 0b00010000) >> 4; 97 | //encrypt 98 | uint8_t isComplex = (flag & 0b00100000) >> 5; 99 | //encrypt 100 | uint8_t preset = (flag & 0b01000000) >> 6; 101 | ```` 102 | 103 | ## 注意点 104 | 105 | 1:初始化data时,如果byte的数据不够,后面的数据会随机生成,有时会带来潜在的bug 106 | 107 | NSData *data = [[NSMutableData alloc]initWithLength:40]; 108 | Byte datatime[] = {0x1e,0x07,0x01,0x01,0x02,0x03}; //2017-01-01 2:03 109 | NSData *data1 = [NSData dataWithBytes:&datatime length:40]; 110 | 111 | data: <00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000> 112 | data1:<1e070101 0203401b 03000061 0000601d 03000061 00006098 835aff7f 00004cb4 f3050100 00006098> 113 | 114 | 115 | 116 | ## 参考 117 | 118 | - [difference-between-sizeof-and-length-of-nsdata](http://stackoverflow.com/questions/25624633/difference-between-sizeof-and-length-of-nsdata) 119 | -------------------------------------------------------------------------------- /0_Foundation/objc代码块的使用.md: -------------------------------------------------------------------------------- 1 | > objc中可以合理使用代码块的特性,使局部变量更清晰 2 | 3 | 4 | 一个 GCC 非常模糊的特性,以及 Clang 也有的特性是,代码块如果在闭合的圆括号内的话,会返回最后语句的值 5 | 6 | ````objc 7 | NSURL *url = ({ 8 | NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, endpoint]; 9 | [NSURL URLWithString:urlString]; 10 | }); 11 | 12 | ```` -------------------------------------------------------------------------------- /0_Foundation/objective 和swift混搭使用.md: -------------------------------------------------------------------------------- 1 | ## objective 和swift混搭使用 2 | 3 | - 1:objcetive 向swift注册对象 4 | 5 | 手动在xxx-Bridging-Header.h 文字中import头文件,例如:#import "CommonOC.h" 6 | 7 | - 2:在swift中引入objective类 8 | 9 | - 3:在使用的object中引入文件:#import "xxx-Swift.h" 10 | 11 | ** !!!!!!!!注意!!:1会报错2无智能感应3注意大小写 ** 12 | -------------------------------------------------------------------------------- /0_Foundation/objective-c中模拟c语言的函数调用方法.md: -------------------------------------------------------------------------------- 1 | ## objective-c中模拟c语言的函数调用方法 2 | > 在很多第三方objc库中,你会看到一些很优雅的函数调用方法,例如masonry中,定义约束的函数 3 | 4 | ````objc 5 | 6 | [row1 mas_makeConstraints:^(MASConstraintMaker *make) { 7 | make.right.and.left.equalTo(view); 8 | make.height.equalTo(view.mas_height).multipliedBy(0.25); 9 | make.top.equalTo(view.mas_top); 10 | }]; 11 | 12 | ```` 13 | 14 | ** 注意点: **(1)and属性: 15 | 16 | ````objc 17 | 对应的源码 18 | - (MASConstraint *)and { 19 | return self; 20 | } 21 | ````objc 22 | 23 | and方法什么都没做,只是返回了自己,一个好的方法名,是可以让你写的方法可以读出来,and的存在的意义就是让方法读出来更通顺。我们读下面的两个方法试试看 24 | 25 | ````objc 26 | make.right.and.left.equalTo(view);//很通顺,可以读出来并且很容易理解其中的意思 27 | make.right.left.equalTo(view);//不通顺,right是什么,怎么还有left对象? 28 | 29 | ```` 30 | 31 | 类似的,我们还可以定义一些with,then,together等等,加入这些连词,让方法更优雅。 32 | 33 | 34 | ** 注意点: **(2)方法 ````objc equalTo(view.mas_height).multipliedBy(0.25) ```` 35 | 36 | 这种括号式的方法调用体并不是objc的消息式的方法调用,这个符合c语言的方法调用,我们看看背后的实现: 37 | 38 | ````objc 39 | 40 | .h中 41 | - (MASConstraint * (^)(id attr))equalTo; 42 | - (MASConstraint * (^)(CGFloat multiplier))multipliedBy; 43 | 44 | .m中 45 | - (MASConstraint * (^)(id))equalTo { 46 | return ^id(id attribute) { 47 | return self.equalToWithRelation(attribute, NSLayoutRelationEqual); 48 | }; 49 | } 50 | 51 | - (MASConstraint * (^)(CGFloat multiplier))multipliedBy { MASMethodNotImplemented(); } 52 | 53 | ```` 54 | 55 | what?这个是什么奇怪的东西? 其实这个就是一个一个objc的方法,返回值是一个block,再实现中,返回一个block执行的结果,我们按照他的模式定义一个add方法试一试 56 | 57 | ````objc 58 | 59 | .h 60 | -(int (^)(int a,int b)) add; 61 | 62 | .m 63 | -(int (^)(int, int))add{ 64 | return ^int(int a,int b){ 65 | return a+b; 66 | }; 67 | } 68 | 69 | ```` 70 | 71 | 方法的调用: 72 | 73 | ````objc 74 | NSLog(@"%d",testClass.add(1,2)); 75 | ```` 76 | 77 | ## 其他疑问 78 | 79 | 有的人或许觉得直接定义c语言的函数,就能做上面的事情,其实不是的,大家可以写一个试试看。它主要存在2个缺点 80 | 81 | ````objc 82 | int add1(int a,int b){ 83 | return a+b; 84 | } 85 | 86 | ```` 87 | 88 | - 1:c语言定义的函数只属于所在的文件中且不依赖于对象,这样定义的函数可以写成add(1,2); 但是不可能写成testClass.add(1,2); 89 | 90 | - 2:函数内部不能直接通过成员变量名访问某个对象的成员变量 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /0_Foundation/strong和copy的使用区别.md: -------------------------------------------------------------------------------- 1 | 2 | ## 用法总结 3 | 4 | - 1:copy:一般来说,有对应Mutab版本的类型,在声明属性是,使用copy关键字作为声明,例如````等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDic```` ,此外block也用过使用copy 5 | 6 | - 2:strong:出copy的绝大多数情况下使用strong关键字。 7 | 8 | - 3:NSMutableString、NSMutableArray、NSMutableDic不能使用copy类型,否则调用mubtab版本的方法时直接会抛异常。 9 | 10 | 说到底,其实就是不同的修饰符,对应不同的setter方法, 11 | 1. strong对应的setter方法,是将_property先release(_property release),然后将参数retain(property retain),最后是_property = property。 12 | 2. copy对应的setter方法,是将_property先release(_property release),然后拷贝参数内容(property copy),创建一块新的内存地址,最后_property = property。 13 | 14 | ## 给NSArray使用错误关键词的反例(NSString错误同理) 15 | 16 | LYWUser.h 17 | 18 | ````objc 19 | 20 | @interface LYWUser : NSObject 21 | @property (strong) NSArray *arry_strong; 22 | @property (copy) NSArray *arry_copy; 23 | ... 24 | 25 | @end 26 | 27 | ```` 28 | 29 | ````objc 30 | 31 | @interface Person : NSObject 32 | @property (strong, nonatomic) NSArray *bookArray1; 33 | @property (copy, nonatomic) NSArray *bookArray2; 34 | @end 35 | 36 | 37 | 38 | 39 | //NSArray 为什么使用copy而不用strong,因为有可能在无意识情况下修改数据 40 | - (void)test2{ 41 | LYWUser *user = [[LYWUser alloc]init]; 42 | NSMutableArray *marry = [NSMutableArray arrayWithObjects:@"a",@"b", nil]; 43 | user.arry_strong = marry; 44 | user.arry_copy = marry; 45 | [marry addObject:@"c"]; 46 | 47 | NSLog(@"arry_strong:%@ arry_copy:%@",user.arry_strong,user.arry_copy); 48 | // 49 | // 2016-02-15 15:24:51.028 foo[4488:323714] arry_strong:( 50 | // a, 51 | // b, 52 | // c 53 | // ) 54 | // arry_copy:( 55 | // a, 56 | // b 57 | // ) 58 | // 59 | // 60 | } 61 | 62 | ```` 63 | 64 | 可以看到,如果使用strong修饰,在修改marry数组的值后会使arry_strong的值也发生变化,这个往往并不是我们希望看到的。 65 | 66 | 同理,NSString使用strong也会有这样的问题 67 | 68 | ````objc 69 | //NSString 为什么使用copy而不用strong,因为有可能在无意识情况下修改数据 70 | - (void)test3{ 71 | LYWUser *user = [LYWUser factoryA]; 72 | NSMutableString *str = [NSMutableString stringWithString:@"a"]; 73 | user.str_copy = str; 74 | user.str_strong = str; 75 | [str appendString:@"b"]; 76 | NSLog(@"str_copy:%@ str_strong:%@",user.str_copy,user.str_strong); 77 | // 2016-02-15 15:56:55.297 foo[4858:343980] str_copy:a str_strong:ab 78 | 79 | } 80 | ```` 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /0_Foundation/weakSelf和strongSelf.md: -------------------------------------------------------------------------------- 1 | > 在block中常常会用到weakSelf和strong来处理block的产生循环引用的问题。 2 | 3 | ## 使用情况 4 | 5 | - 直接在 block 里面使用关键词 self 6 | - 在 block 外定义一个 __weak 的 引用到 self,并且在 block 里面使用这个弱引用 7 | - 在 block 外定义一个 __weak 的 引用到 self,并在在 block 内部通过这个弱引用定义一个 __strong 的引用。 8 | 9 | ### 直接在 block 里面使用关键词 self 10 | 11 | 当block并没有被self对象所引用时,一般可以直接使用self,例如: 12 | 13 | ````objc 14 | dispatch_block_t completionBlock2 = ^(){ 15 | NSLog(@"complete");NSLog(@"%@", self); 16 | }; 17 | 18 | [self presentViewController:myController 19 | animated:YES 20 | completion:completionBlock2]; 21 | 22 | ```` 23 | 24 | ### 使用weakself 25 | 26 | 当block对象被self持有时,一定要使用weakself避免循环引用。 27 | 28 | ```` 29 | __weak typeof(self) weakSelf = self; 30 | self.completionHandler = ^{ 31 | NSLog(@"%@", weakSelf); 32 | }; 33 | 34 | MyViewController *myController = [[MyViewController alloc] init...]; 35 | [self presentViewController:myController 36 | animated:YES 37 | completion:self.completionHandler]; 38 | ```` 39 | 40 | ### 使用__strong 41 | 42 | 当block中执行多个self的方法时,推荐在block中使用strongSelf,这样更严谨和安全,因为如果weakSelf有可能在一些方法中被释放导致后续方法无法执行。 43 | 44 | ```` 45 | __weak typeof(self) weakSelf = self; 46 | myObj.myBlock = ^{ 47 | __strong typeof(self) strongSelf = weakSelf; 48 | if (strongSelf) { 49 | [strongSelf doSomething]; // strongSelf != nil 50 | // preemption, strongSelf still not nil(抢占的时候,strongSelf 还是非 nil 的) 51 | [strongSelf doSomethingElse]; // strongSelf != nil 52 | } 53 | else { 54 | // Probably nothing... 55 | return; 56 | } 57 | }; 58 | ```` 59 | 60 | ### 总结 61 | 62 | 一般来说:如果block不是属性则使用self,是属性但block中调用单个self的方法时用weakSelf,多个方法用strongSelf 63 | 64 | 65 | ## 简单处理weakself和strongSelf 66 | 67 | ````objc 68 | __weak __typeof(self) weakSelf = self; 69 | __strong __typeof(weakSelf) strongSelf = weakSelf; 70 | 71 | ```` 72 | 73 | 建议把这两段代码添加到xcode snippet library中。 74 | 75 | 添加方式:直接把代码行分别拖入,重新命名snippet,设置title和complete shortcut(快捷键),类型选择code expresssion。建议title和shortcut都使用weakify和strongify 76 | 77 | ## 例子 78 | 79 | ````objc 80 | __weak __typeof(self) weakSelf = self; 81 | [self executeBlock:^(NSData *data, NSError *error) { 82 | [weakSelf doSomethingWithData:data]; 83 | }]; 84 | 85 | //不要这样 86 | 87 | [self executeBlock:^(NSData *data, NSError *error) { 88 | [self doSomethingWithData:data]; 89 | }]; 90 | ```` 91 | 92 | 多个语句的例子: 93 | 94 | ````objc 95 | __weak __typeof(self)weakSelf = self; 96 | [self executeBlock:^(NSData *data, NSError *error) { 97 | __strong __typeof(weakSelf) strongSelf = weakSelf; 98 | if (strongSelf) { 99 | [strongSelf doSomethingWithData:data]; 100 | [strongSelf doSomethingWithData:data]; 101 | } 102 | }]; 103 | 104 | //不要这样: 105 | 106 | __weak __typeof(self)weakSelf = self; 107 | [self executeBlock:^(NSData *data, NSError *error) { 108 | [weakSelf doSomethingWithData:data]; 109 | [weakSelf doSomethingWithData:data]; 110 | }]; 111 | ```` 112 | 113 | ## 定义宏@weakify和@strongify处理 114 | 115 | 待更新,还没研究清楚实现方式. 116 | 117 | -------------------------------------------------------------------------------- /0_Foundation/while使用runloop阻塞方法返回.md: -------------------------------------------------------------------------------- 1 | while使用runloop阻塞方法返回 2 | 3 | 示例如下 4 | 5 | ````objc 6 | //异步的同步方法 7 | - (void)foo { 8 | __block BOOL isStop = YES; 9 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 10 | isStop = NO; 11 | }); 12 | 13 | while (isStop) { 14 | [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 15 | } 16 | } 17 | ```` 18 | 19 | 如果没有 ` [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; ` 这句话,那么cpu会高到100%,但是加了后,cpu就为0,且可以阻塞方法执行。 20 | 21 | 例如: 22 | 23 | ````objc 24 | //用法 25 | NSLog(@"start foo"); 26 | [self foo]; 27 | //方法会在5秒后继续往下执行 28 | NSLog(@"done foo"); 29 | ```` -------------------------------------------------------------------------------- /0_Foundation/xcode中混用arc和非arc模式.md: -------------------------------------------------------------------------------- 1 | ## xcode中混用arc和非arc模式 2 | > Xcode 项目中我们可以使用 ARC 和非 ARC 的混合模式。 3 | 4 | 如果你的项目使用的非 ARC 模式,则为 ARC 模式的代码文件加入 -fobjc-arc 标签。 5 | 6 | 如果你的项目使用的是 ARC 模式,则为非 ARC 模式的代码文件加入 -fno-objc-arc 标签。 7 | 8 | ## 添加标签的位置 9 | 10 | 打开:你的target -> Build Phases -> Compile Sources. 11 | 12 | 双击对应的 *.m 文件 13 | 14 | 在弹出窗口中输入上面提到的标签 -fobjc-arc / -fno-objc-arc 15 | 16 | 点击 done 保存 -------------------------------------------------------------------------------- /0_Foundation/xcode导入外部项目.md: -------------------------------------------------------------------------------- 1 | ### 1:在xode中选择 add files to project,把需要导入的项目工程文件加入,或者直接把工程文件拖入项目中。 2 | 3 | ### 2:设置Build Phases 4 | 5 | - 选择progect的targets,打开Build Phases标签 6 | - 选择Link Binary With Libraries,点击+,添加xxx.a 7 | - 追加xxx所需要的Frameworks 8 | 9 | ### 3: build setting 中设置Header Search Paths 10 | 11 | 12 | ## 参考 13 | [http://www.open-open.com/lib/view/open1373254405019.html](http://www.open-open.com/lib/view/open1373254405019.html) 14 | 15 | -------------------------------------------------------------------------------- /0_Foundation/xcode调试技巧.md: -------------------------------------------------------------------------------- 1 | ## xcode调试技巧 2 | 3 | - 1:在debugger中输入p 或者po 查看对象 4 | 5 | oc有智能感应,而swift没有 6 | 7 | - 2:NSLog 和 NSAssert的使用 8 | 9 | 例如: NSAssert(i>0,@"大于" , @"小于") 10 | -------------------------------------------------------------------------------- /0_Foundation/xcode静态库使用.md: -------------------------------------------------------------------------------- 1 | ## xcode静态库使用 2 | 3 | 4 | 静态库和动态库在使用上的区别 5 | 6 | - 静态库:链接时,静态库会被完整地复制到可执行文件中, 被多次使用就有多份冗余拷贝 (左图所示) 7 | - 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存 (右图所示) 8 | 9 | 使用 10 | 11 | - 新建项目,cocoa touch static library 12 | - 编写代码 13 | - 设置头文件,build phases -> New Headers phases,选择需要包含的头 14 | - 选择设备(模拟器或者是真机)生成produceName.a文件和header文件 15 | - 编译(选择真机设备,然后 Command+B 编译, libMJRefresh.a 文件从红色变为黑色,然后在选择模拟器Command+B) 16 | - 使用 将 .a 、 .h 、资源文件拖拽到其他项目中即可 17 | 18 | ### 其他说明: 19 | 20 | 静态库区分真机和模拟器的库,右击 “Show In Finder” ,查看制作好的 .a 文件,里面可以看到有多个版本 21 | - Debug-iphoneos 文件夹里面的东西是用在真机上的 22 | - Debug-iphonesimulator 文件夹里面的东西是用在模拟器上的 23 | - 如果 Scheme 是 Release 模式,生成的文件夹就以 Release 开头 24 | - 如果想让一个 .a 文件能同时用在真机和模拟器上,需要进行合并 25 | ```` 26 | lipo -create Debug-iphoneos/xxx.a Debug-iphonesimulator/xxx.a -output xxx.a 27 | //通过 lipo –info libMJRefresh.a 可以查看 .a 的类型(模拟器还是真机) 28 | ```` 29 | 30 | 31 | 32 | ## 参考 33 | [http://www.cocoachina.com/ios/20150226/11182.html](http://www.cocoachina.com/ios/20150226/11182.html) 34 | 35 | -------------------------------------------------------------------------------- /0_Foundation/从本地plist文件中加载数据.md: -------------------------------------------------------------------------------- 1 | ## 从本地plist文件中加载数据 2 | 3 | ````objc 4 | 5 | //user code 6 | NSBundle *bundle = [NSBundle mainBundle]; 7 | NSString *plistPath = [bundle pathForResource:@"event" ofType:@"plist"]; 8 | //获取本地文件列表 NSArray 9 | events = [[NSArray alloc] initWithContentsOfFile:plistPath]; 10 | 11 | ```` -------------------------------------------------------------------------------- /0_Foundation/保存照片和视频到相册.md: -------------------------------------------------------------------------------- 1 | 2 | ## 保存照片到相册 3 | 4 | ````objc 5 | //获取docment目录 6 | NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 7 | NSString * documentDirectory = [paths objectAtIndex:0]; 8 | //文件名 9 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; 10 | [dateFormatter setDateFormat:@"yyyyMMddHHmmss"]; 11 | NSString *timestamp = [dateFormatter stringFromDate:[NSDate date]]; 12 | NSString *photoname = [NSString stringWithFormat:@"homeCare_photo_%@",timestamp]; 13 | NSString *fileName=[documentDirectory stringByAppendingPathComponent:photoname]; 14 | //储存 15 | int result = [player saveVideoSnapshotAt:fileName withWidth:0 andHeight:100]; 16 | NSLog(@"%d",result); 17 | 18 | //打开图片,保存到相册 19 | UIImage *image = [UIImage imageWithContentsOfFile:fileName]; 20 | UIImageWriteToSavedPhotosAlbum(image, self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), nil); 21 | ```` 22 | 23 | ## 保存视频到相册 24 | 25 | ````objc 26 | UISaveVideoAtPathToSavedPhotosAlbum(fileName, self, nil, nil); 27 | ```` -------------------------------------------------------------------------------- /0_Foundation/全局使用appDelegate中的方法.md: -------------------------------------------------------------------------------- 1 | id appDelegate = (id)[UIApplication sharedApplication].delegate; -------------------------------------------------------------------------------- /0_Foundation/共享对象的使用.md: -------------------------------------------------------------------------------- 1 | 2 | ````objc 3 | //共享对象显示 4 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 5 | self.label.text = [defaults stringForKey:@"username"]; 6 | ```` -------------------------------------------------------------------------------- /0_Foundation/内存警告一般处理.md: -------------------------------------------------------------------------------- 1 | 2 | ````objc 3 | - (void)didReceiveMemoryWarning { 4 | [super didReceiveMemoryWarning]; 5 | // Dispose of any resources that can be recreated. 6 | [[NSURLCache sharedURLCache] removeAllCachedResponses]; 7 | } 8 | ```` -------------------------------------------------------------------------------- /0_Foundation/常用类型转换.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ````objc 4 | 5 | //NSString-->int 6 | int intString = [newString intValue]; 7 | //int转字符 8 | NSString *stringInt = [NSString stringWithFormat:@"%d",intString]; 9 | 10 | //NSString-->float 11 | float floatString = [newString floatValue]; 12 | //float转NSString 13 | NSString *stringFloat = [NSString stringWithFormat:@"%f",intString]; 14 | 15 | //NSData-->NSString 16 | NSString *aString = [[NSString alloc] initWithData:adata encoding:NSUTF8StringEncoding]; 17 | //NSString --> NSData 18 | NSString *aString = @"1234"; 19 | NSData *aData = [aString dataUsingEncoding: NSUTF8StringEncoding]; 20 | 21 | //NSData --> Byte 22 | NSString *testString = @"1234567890"; 23 | NSData *testData = [testString dataUsingEncoding: NSUTF8StringEncoding]; 24 | Byte *testByte = (Byte *)[testData bytes]; 25 | //Byte --> NSData 26 | Byte byte[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}; 27 | NSData *adata = [[NSData alloc] initWithBytes:byte length:24]; 28 | 29 | //NSData --> UIImage 30 | UIImage *aimage = [UIImage imageWithData: imageData]; 31 | //例:从本地文件沙盒中取图片并转换为NSData 32 | NSString *path = [[NSBundle mainBundle] bundlePath]; 33 | NSString *name = [NSString stringWithFormat:@"ceshi.png"]; 34 | NSString *finalPath = [path stringByAppendingPathComponent:name]; 35 | NSData *imageData = [NSData dataWithContentsOfFile: finalPath]; 36 | UIImage *aimage = [UIImage imageWithData: imageData]; 37 | //UIImage-> NSData 38 | NSData *imageData = UIImagePNGRepresentation(aimae); 39 | 40 | 41 | //NSData --> MSMutableData 42 | NSData *data=[[NSData alloc]init]; 43 | NSMutableData *mdata=[[NSMutableData alloc]init]; 44 | mdata=[NSData dataWithData:data]; 45 | 46 | 47 | //base64 48 | //Data -> String 49 | NSString* dataString = [data base64EncodedStringWithOptions:0]; 50 | //string -> Data 51 | NSData *data = [[NSData alloc] initWithBase64EncodedString:advertisement options:0]; 52 | ```` -------------------------------------------------------------------------------- /0_Foundation/弃用的方法注释.md: -------------------------------------------------------------------------------- 1 | # swift弃用的方法注释 2 | 3 | 示例: 4 | 5 | ````swift 6 | //说明: 版本号 开始版本 弃用版本 提示内容 7 | @available(iOS, introduced=2.0, deprecated=9.0, message="Use -[UIViewController preferredStatusBarStyle]") 8 | //方法名 9 | public func setStatusBarStyle(statusBarStyle: UIStatusBarStyle, animated: Bool) 10 | ```` 11 | 12 | 13 | 示例:@property(retain, readonly, nullable) NSNumber *RSSI NS_DEPRECATED(NA, NA, 5_0, 8_0); 14 | 15 | 如果有四个数字表示同时支持macOSX和iOS,前两个是OSX,后两个是iOS,分别为开始版本和结束版本 16 | -------------------------------------------------------------------------------- /0_Foundation/深复制和浅复制.md: -------------------------------------------------------------------------------- 1 | 2 | ````objc 3 | [immutableObject copy] // 浅复制 4 | [immutableObject mutableCopy] //深复制 5 | [mutableObject copy] //深复制 6 | [mutableObject mutableCopy] //深复制 7 | 8 | 9 | [immutableObject copy] // 浅复制 10 | [immutableObject mutableCopy] //单层深复制 11 | [mutableObject copy] //单层深复制 12 | [mutableObject mutableCopy] //单层深复制 13 | ```` 14 | 15 | ## 参考链接 16 | 17 | - [iOS 集合的深复制与浅复制](https://www.zybuluo.com/MicroCai/note/50592) -------------------------------------------------------------------------------- /0_Foundation/类簇class cluster.md: -------------------------------------------------------------------------------- 1 | > an architecture that groups a number of private, concrete subclasses under a public, abstract superclass. (一个在共有的抽象超类下设置一组私有子类的架构) 2 | 3 | Class cluster 是 Apple 对抽象工厂设计模式的称呼 4 | 5 | class cluster 的想法很简单: 使用信息进行(类的)初始化处理期间,会使用一个抽象类(通常作为初始化方法的参数或者判定环境的可用性参数)来完成特定的逻辑或者实例化一个具体的子类。而这个"Public Facing(面向公众的)"类,必须非常清楚他的私有子类,以便在面对具体任务的时候有能力返回一个恰当的私有子类实例。对调用者来说只需知道对象的各种API的作用即可。这个模式隐藏了他背后复杂的初始化逻辑,调用者也不需要关心背后的实现。 6 | 7 | Class clusters 在 Apple 的Framework 中广泛使用:一些明显的例子比如 NSNumber 可以返回不同类型给你的子类,取决于 数字类型如何提供 (Integer, Float, etc...) 或者 NSArray 返回不同的最优存储策略的子类。 8 | 9 | 这个模式的精妙的地方在于,调用者可以完全不管子类,事实上,这可以用在设计一个库,可以用来交换实际的返回的类,而不用去管相关的细节,因为它们都遵从抽象超类的方法。 10 | 11 | ** 我们的经验是使用类簇可以帮助移除很多条件语句。 ** 12 | 13 | 一个经典的例子是如果你有为 iPad 和 iPhone 写的一样的 UIViewController 子类,但是在不同的设备上有不同的行为。 14 | 15 | 比较基础的实现是用条件语句检查设备,然后执行不同的逻辑。虽然刚开始可能不错,但是随着代码的增长,运行逻辑也会趋于复杂。 一个更好的实现的设计是创建一个抽象而且宽泛的 view controller 来包含所有的共享逻辑,并且对于不同设备有两个特别的子例。 16 | 17 | 通用的 view controller 会检查当前设备并且返回适当的子类。 18 | 19 | 20 | ````objc 21 | @implementation ZOCKintsugiPhotoViewController 22 | 23 | - (id)initWithPhotos:(NSArray *)photos 24 | { 25 | if ([self isMemberOfClass:ZOCKintsugiPhotoViewController.class]) { 26 | self = nil; 27 | 28 | if ([UIDevice isPad]) { 29 | self = [[ZOCKintsugiPhotoViewController_iPad alloc] initWithPhotos:photos]; 30 | } 31 | else { 32 | self = [[ZOCKintsugiPhotoViewController_iPhone alloc] initWithPhotos:photos]; 33 | } 34 | return self; 35 | } 36 | return [super initWithNibName:nil bundle:nil]; 37 | } 38 | 39 | @end 40 | 41 | ```` 42 | 43 | 这个子例程展示了如何创建一个类簇。 44 | 45 | - 使用[self isMemberOfClass:ZOCKintsugiPhotoViewController.class]防止子类中重载初始化方法,避免无限递归。当[[ZOCKintsugiPhotoViewController alloc] initWithPhotos:photos]被调用时,上面条件表达式的结果将会是True。 46 | 47 | - self = nil的目的是移除ZOCKintsugiPhotoViewController实例上的所有引用,实例(抽象类的实例)本身将会解除分配( 当然ARC也好MRC也好dealloc都会发生在Main Runloop这一次的结束时)。 48 | 49 | - 接下来的逻辑就是判断哪一个私有子类将被初始化。我们假设在iPhone上运行这段代码并且ZOCKintsugiPhotoViewController_iPhone没有重载initWithPhotos:方法。这种情况下,当执行self = [[ZOCKintsugiPhotoViewController_iPhone alloc] initWithPhotos:photos];,ZOCKintsugiPhotoViewController将会被调用,第一次检查将会在这里发生,鉴于ZOCKintsugiPhotoViewController_iPhone不完全是ZOCKintsugiPhotoViewController,表达式[self isMemberOfClass:ZOCKintsugiPhotoViewController.class]将会是False,于是就会调用[super initWithNibName:nil bundle:nil],于是就会进入ZOCKintsugiPhotoViewController的初始化过程,这时候因为调用者就是ZOCKintsugiPhotoViewController本身,这一次的检查必定为True,接下来就会进行正确的初始化过程。(NOTE:这里必须是完全遵循Designated initializer 以及Secondary initializer的设计规范的前提下才会其效果的!不明白这个规范的可以后退一步熟悉这种规范在回头来看这个说明) -------------------------------------------------------------------------------- /1_UIKit/3D touch主屏幕添加快捷action方法.md: -------------------------------------------------------------------------------- 1 | > 主要有2种方法,通过.plist声明和代码实现。 2 | 3 | ## .plist声明 4 | 5 | 6 | ```` 7 | UIApplicationShortcutItems 8 | 9 | 10 | 11 | UIApplicationShortcutItemTitle 12 | New Message 13 | 14 | UIApplicationShortcutItemSubtitle 15 | open-favorites 16 | 17 | UIApplicationShortcutItemIconType 18 | UIApplicationShortcutIconTypeCompose 19 | 20 | 22 | 23 | UIApplicationShortcutItemType 24 | com.mycompany.myapp.newmessage 25 | 26 | UIApplicationShortcutItemUserInfo 27 | 28 | key2 29 | value2 30 | 31 | 32 | 33 | UIApplicationShortcutItemIconFile 34 | open-favorites 35 | UIApplicationShortcutItemTitle 36 | Favorites 37 | UIApplicationShortcutItemType 38 | com.mycompany.myapp.openfavorites 39 | UIApplicationShortcutItemUserInfo 40 | 41 | key1 42 | value1 43 | 44 | 45 | 46 | ```` 47 | 48 | 49 | ## 代码动态实现示例 50 | 51 | ````swift 52 | 53 | //动态注册Home Screen Quick Actions 54 | func registHomeScreenQuickActions(){ 55 | let item1 = UIApplicationShortcutItem(type: "com.mycompany.myapp.newmessage", localizedTitle: "title", localizedSubtitle: "subtitle", icon: UIApplicationShortcutIcon(type: .Home), userInfo: nil); 56 | // UIApplicationShortcutItem 代表一个item 57 | // type: 唯一标示符的属性 58 | // localizedTitle: 显示的标题 59 | // localizedSubtitle: 显示的二级标题 60 | // icon:显示的图片,可以自定义,也可以使用系统提供的样式 61 | // userInfo: 包含一些信息 62 | 63 | // 自定义的icon 64 | //icon:UIApplicationShortcutIcon(templateImageName: "like") 65 | UIApplication.sharedApplication().shortcutItems = [item1]; 66 | } 67 | 68 | ```` 69 | 70 | ## 获取启动入口和参数 71 | 72 | 想要接收3d touch启动点击的选项和配置的上下文数据,可以在 ` AppDelegate ` 中实现委托 ` application performActionForShortcutItem ` 例如: 73 | 74 | ````swift 75 | //接收Home Screen Quick Actions启动参数 76 | func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) { 77 | NSLog("%@", shortcutItem); 78 | if let userInfo = shortcutItem.userInfo { 79 | NSLog("userinfo:%@", userInfo); 80 | } 81 | } 82 | ```` 83 | 84 | ## 判断是否支持3d touch 85 | 86 | ````swift 87 | // 判断设备是否支持 3D Touch 88 | if self.traitCollection.forceTouchCapability == UIForceTouchCapability.Available { 89 | print("支持") 90 | } else { 91 | print("不支持") 92 | } 93 | ```` 94 | -------------------------------------------------------------------------------- /1_UIKit/3Dtouch系统图标类型.md: -------------------------------------------------------------------------------- 1 | `UIApplicationShortcutItemIconType` 这个key可以使用一些系统自定义的icon, 2 | 可选的类型的枚举如下,详细介绍和每个图片的样子可以参考[这里](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationShortcutIcon_Class/index.html#//apple_ref/c/tdef/UIApplicationShortcutIconType) 3 | 4 | 5 | ```` 6 | enum UIApplicationShortcutIconType : Int { 7 | case Compose 8 | case Play 9 | case Pause 10 | case Add 11 | case Location 12 | case Search 13 | case Share 14 | case Prohibit 15 | case Contact 16 | case Home 17 | case MarkLocation 18 | case Favorite 19 | case Love 20 | case Cloud 21 | case Invitation 22 | case Confirmation 23 | case Mail 24 | case Message 25 | case Date 26 | case Time 27 | case CapturePhoto 28 | case CaptureVideo 29 | case Task 30 | case TaskCompleted 31 | case Alarm 32 | case Bookmark 33 | case Shuffle 34 | case Audio 35 | case Update 36 | } 37 | OBJECTIVE-C 38 | typedef enum UIApplicationShortcutIconType : NSInteger { 39 | UIApplicationShortcutIconTypeCompose, 40 | UIApplicationShortcutIconTypePlay, 41 | UIApplicationShortcutIconTypePause, 42 | UIApplicationShortcutIconTypeAdd, 43 | UIApplicationShortcutIconTypeLocation, 44 | UIApplicationShortcutIconTypeSearch, 45 | UIApplicationShortcutIconTypeShare, 46 | UIApplicationShortcutIconTypeProhibit, 47 | UIApplicationShortcutIconTypeContact, 48 | UIApplicationShortcutIconTypeHome, 49 | UIApplicationShortcutIconTypeMarkLocation, 50 | UIApplicationShortcutIconTypeFavorite, 51 | UIApplicationShortcutIconTypeLove, 52 | UIApplicationShortcutIconTypeCloud, 53 | UIApplicationShortcutIconTypeInvitation, 54 | UIApplicationShortcutIconTypeConfirmation, 55 | UIApplicationShortcutIconTypeMail, 56 | UIApplicationShortcutIconTypeMessage, 57 | UIApplicationShortcutIconTypeDate, 58 | UIApplicationShortcutIconTypeTime, 59 | UIApplicationShortcutIconTypeCapturePhoto, 60 | UIApplicationShortcutIconTypeCaptureVideo, 61 | UIApplicationShortcutIconTypeTask, 62 | UIApplicationShortcutIconTypeTaskCompleted, 63 | UIApplicationShortcutIconTypeAlarm, 64 | UIApplicationShortcutIconTypeBookmark, 65 | UIApplicationShortcutIconTypeShuffle, 66 | UIApplicationShortcutIconTypeAudio, 67 | UIApplicationShortcutIconTypeUpdate 68 | } UIApplicationShortcutIconType; 69 | ```` -------------------------------------------------------------------------------- /1_UIKit/UIScrenn_UIView_UIWindow.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 视图 4 | 5 | ** 重要对象介绍: ** 6 | UIScreen(屏幕):包含 mainScreen 7 | 8 | ** 重要属性:** 9 | bounds ,applicationFrame 10 | 11 | ````objc 12 | //示例 13 | CGrect screenBounds = [[UIScreen mainScreen] bounds];//返回的是带有状态栏的Rect (0.0,0.0,320.0,480.0) 14 | ```` 15 | 16 | ## UIView(画布) 17 | 应用程序视图的基本单位,可以添加子视图 18 | 19 | ## UIWindow(画框) 20 | 21 | 应用程序界面的根元素,包含许多UIView,但是其继承自UIView 22 | 23 | ````objc 24 | 25 | 示例:self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] 26 | 27 | ```` 28 | -------------------------------------------------------------------------------- /1_UIKit/UIView动画.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ## 使用animateWithDuration 5 | 6 | ````swift 7 | 8 | 9 | UIView.animateWithDuration(0.2, delay: 0.5, options: UIViewAnimationOptions.CurveEaseIn, animations: { () -> Void in 10 | //位置运动 11 | theView.frame = CGRect(x: theView.frame.origin.x+100, y: theView.frame.origin.y, width: theView.frame.size.width, height: theView.frame.height) 12 | //颜色渐变 13 | theView.backgroundColor = UIColor.greenColor() 14 | //透明度渐变 15 | theView.alpha = 0.5 16 | }) { (isCompletion) -> Void in 17 | NSLog("completion") 18 | } 19 | 20 | // 21 | 22 | ```` 23 | 24 | ## 使用begin和commit模式示例 25 | 26 | ````swift 27 | 28 | //开始动画配置 29 | UIView.beginAnimations("view1Animation", context: nil) 30 | //运动时间 31 | UIView.setAnimationDuration(0.2) 32 | //设置运动开始和结束的委托 animationDidStart and animationDidStop 33 | UIView.setAnimationDelegate(self) 34 | /* 35 | 缓动方式 36 | EaseInOut // slow at beginning and end 37 | EaseIn // slow at beginning 38 | EaseOut // slow at end 39 | Linear 40 | */ 41 | UIView.setAnimationCurve(.EaseIn) 42 | //位置运动 43 | theView.frame = CGRect(x: theView.frame.origin.x+100, y: theView.frame.origin.y, width: theView.frame.size.width, height: theView.frame.height) 44 | //颜色渐变 45 | theView.backgroundColor = UIColor.greenColor() 46 | //透明度渐变 47 | theView.alpha = 0.5 48 | //动画开始 49 | UIView.commitAnimations() 50 | 51 | ```` 52 | 53 | 54 | ## imageview的逐帧动画 55 | 56 | ````objc 57 | 58 | 59 | NSArray *images = [NSArray arrayWithObjects:[UIImage imageNamed:@"1"],[UIImage imageNamed:@"2"],[UIImage imageNamed:@"3"],[UIImage imageNamed:@"4"],[UIImage imageNamed:@"5"],[UIImage imageNamed:@"6"], nil]; 60 | UIImageView *image = [[UIImageView alloc]initWithFrame:self.view.frame]; 61 | image.animationImages = images; 62 | image.animationDuration = 0.5f; 63 | image.animationRepeatCount = 0;//无限重复 64 | [self.view addSubview:image]; 65 | [image startAnimating]; 66 | 67 | //button旋转 68 | [UIView animateWithDuration:2.0f animations:^{ 69 | [btn setTransform:CGAffineTransformMakeRotation(M_PI/3)]; 70 | }]; 71 | 72 | 73 | ```` 74 | -------------------------------------------------------------------------------- /1_UIKit/iOS修改状态栏样式.md: -------------------------------------------------------------------------------- 1 | 2 | ## iOS9修改状态栏字体颜色 3 | 4 | 第一步:在info.plist中添加一个字段:UIViewControllerBasedStatusBarAppearance 设置值为 NO 5 | 6 | 第二步,设置状态栏颜色: 7 | UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent 8 | 9 | 10 | ## 注意点 11 | 12 | 1:ios 9 以下操作方式和上面的不同 13 | 14 | - 第一步的key为:view controller -base status bar 15 | - 第二步的方法为:[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:NO]; 16 | 17 | 2:ios 9 修改状态栏会产生一个警告,这个是xcode的bug,可以忽略 [参考地址](https://forums.developer.apple.com/thread/13683) 18 | 19 | //iOS 9 推荐使用 UIViewController preferredStatusBarStyle方法 20 | @available(iOS, introduced=2.0, deprecated=9.0, message="Use -[UIViewController preferredStatusBarStyle]") 21 | 22 | 这里需要重写preferredStatusBarStyle方法,示例: 23 | 24 | ````swift 25 | 26 | var _statusBarStyle:UIStatusBarStyle = UIStatusBarStyle.Default 27 | var statusBarStyle:UIStatusBarStyle { 28 | set{ 29 | self._statusBarStyle = newValue 30 | self.setNeedsStatusBarAppearanceUpdate() 31 | } 32 | get{ 33 | return self._statusBarStyle 34 | } 35 | } 36 | override func preferredStatusBarStyle() -> UIStatusBarStyle { 37 | return self._statusBarStyle 38 | } 39 | 40 | 41 | var _statusBarHidden:Bool = false; 42 | var statusBarHidden:Bool{ 43 | set{ 44 | self._statusBarHidden = newValue 45 | self.setNeedsStatusBarAppearanceUpdate() 46 | } 47 | get{ 48 | return self._statusBarHidden 49 | } 50 | } 51 | override func prefersStatusBarHidden() -> Bool { 52 | return self.statusBarHidden 53 | } 54 | 55 | 56 | ```` -------------------------------------------------------------------------------- /1_UIKit/presention和presenting通信.md: -------------------------------------------------------------------------------- 1 | ## presention和presenting直接的通信 2 | 3 | - 1:通过委托的方式,presention实例化一个交互方法的委托类,presenting的delegate指向presention 4 | 5 | - 2:presenting直接调用presention的方法 6 | 7 | ````swift 8 | 9 | //找Controller中的xxxMethod方法,找到后调用,优先在本类中招,找不到才往上游找 10 | UIApplication.sharedApplication().sendAction("xxxMethod:", to: nil, from: self, forEvent: nil) 11 | 12 | ```` -------------------------------------------------------------------------------- /1_UIKit/view图层层级.md: -------------------------------------------------------------------------------- 1 | ## view 图层层级 2 | 3 | ````siwft 4 | 5 | - (void)bringSubviewToFront:(UIView *)view;将一个UIView显示在最前面 6 | - (void)sendSubviewToBack:(UIView *)view;将一个UIView层推送到背后 7 | 8 | ```` 9 | -------------------------------------------------------------------------------- /1_UIKit/半透明模态弹出框.md: -------------------------------------------------------------------------------- 1 | ## 使用storyboard或xib方式 2 | 3 | 1:设置presentation为:Over Current Context 4 | 2:设置弹出的ViewController的view的background为 clear color 5 | 6 | ## 使用代码方式 7 | 8 | 1:presention (原ViewController) 9 | 10 | ````objc 11 | vc.modalPresentationStyle = UIModalPresentationOverCurrentContext 12 | [self presentViewController:vc animated:YES completion:nil] 13 | ```` 14 | 15 | 2:presenting (弹出的ViewController) 16 | 17 | ````objc 18 | self.view.backgroundColor = [UIColor clearColor]; 19 | ```` 20 | -------------------------------------------------------------------------------- /1_UIKit/常用获取屏幕尺寸方法.md: -------------------------------------------------------------------------------- 1 | ## app尺寸,去掉状态栏 2 | ````objc 3 | CGRect r = [ UIScreen mainScreen ].applicationFrame; 4 | ```` 5 | 6 | ## 屏幕尺寸 7 | ````objc 8 | CGRect rx = [ UIScreen mainScreen ].bounds; 9 | ```` 10 | 11 | ## 状态栏尺寸 12 | ````objc 13 | CGRect rect = [[UIApplication sharedApplication] statusBarFrame]; 14 | ```` 15 | 16 | ## uiview尺寸 17 | ````objc 18 | CGRect rect = self.view.frame; 19 | 20 | ```` -------------------------------------------------------------------------------- /1_UIKit/手势.md: -------------------------------------------------------------------------------- 1 | ## iOS手势操作 2 | 3 | ### 1:继承 委托 4 | 5 | ### 2:设置委托 6 | 7 | ````objc 8 | 9 | UIPanGestureRecognizer *panRcognize=[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 10 | panRcognize.delegate=self; 11 | [panRcognize setEnabled:YES]; 12 | [panRcognize delaysTouchesEnded]; 13 | [panRcognize cancelsTouchesInView]; 14 | 15 | [self.view addGestureRecognizer:panRcognize]; 16 | 17 | ```` 18 | 19 | ### 3:监控事件 20 | 21 | ````objc 22 | 23 | #pragma UIGestureRecognizer Handles 24 | - (void)handlePan:(UIPanGestureRecognizer *)recognizer { 25 | 26 | //获取的是x y 的增量 27 | NSLog(@"--移动的手势----- x:%f,y:%f",[recognizer translationInView:self.view].x, 28 | [recognizer translationInView:self.view].y); 29 | //获取的是x y 的位置 30 | NSLog(@"--移动的手势-位置----- x:%f,y:%f",[recognizer locationInView:self.view].x, 31 | [recognizer locationInView:self.view].y); 32 | } 33 | ```` 34 | 35 | ### uiview手势移动 36 | 37 | ````objc 38 | 39 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 40 | //获取inner point 41 | self.innerTouchPoint = [[touches anyObject]locationInView:self.leftView]; 42 | 43 | } 44 | -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ 45 | CGPoint point = [[touches anyObject]locationInView:(self.view)]; 46 | CGFloat y = point.y; 47 | CGFloat x = point.x; 48 | 49 | NSLog(@"--移动的手势-增量----- point:%f,%f",x,y); 50 | 51 | self.leftView.frame = CGRectMake(x-self.innerTouchPoint.x, y-self.innerTouchPoint.y, 30, 400); 52 | 53 | // NSLog(@"--移动的手势-位置----- x:%f,y:%f",[recognizer locationInView:self.view].x, 54 | // [event locationInView:self.view].y); 55 | } 56 | -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 57 | 58 | } 59 | 60 | ```` 61 | -------------------------------------------------------------------------------- /1_UIKit/控件/UIAlertController使用.md: -------------------------------------------------------------------------------- 1 | ````objc 2 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:@"" preferredStyle:UIAlertControllerStyleActionSheet]; 3 | UIAlertAction *act1 = [UIAlertAction actionWithTitle:@"title1" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 4 | 5 | }]; 6 | UIAlertAction *act2 = [UIAlertAction actionWithTitle:@"title2" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 7 | 8 | }]; 9 | UIAlertAction *act3 = [UIAlertAction actionWithTitle:@"cannel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 10 | 11 | }]; 12 | UIAlertAction *act4 = [UIAlertAction actionWithTitle:@"Destructive" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { 13 | 14 | }]; 15 | 16 | [alert addAction:act1]; 17 | [alert addAction:act2]; 18 | [alert addAction:act3]; 19 | [alert addAction:act4]; 20 | 21 | [self presentViewController:alert animated:YES completion:^{ 22 | 23 | }]; 24 | ```` -------------------------------------------------------------------------------- /1_UIKit/控件/UIImageView添加点击事件.md: -------------------------------------------------------------------------------- 1 | ## UIImageView添加点击事件 2 | 3 | ````objc 4 | image.userInteractionEnabled = YES;//it is very improtant!!! 5 | [image addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(headportraitClicked:)]]; 6 | ```` 7 | 8 | ## 获取调用手势的uiview 9 | 10 | ````objc 11 | (void)btnClicked:(UITapGestureRecognizer *)sender{ 12 | UIButton *btn = (UIButton *)sender.view; 13 | } 14 | ```` -------------------------------------------------------------------------------- /1_UIKit/控件/UIImageView的contentMode属性.md: -------------------------------------------------------------------------------- 1 | ## UIImageView 的contentMode属性 2 | 3 | ````objc 4 | 5 | UIViewContentModeScaleToFill 6 | 7 | UIViewContentModeScaleAspectFit 8 | 9 | UIViewContentModeScaleAspectFill 10 | 11 | UIViewContentModeRedraw 12 | 13 | UIViewContentModeCenter 14 | 15 | UIViewContentModeTop 16 | 17 | UIViewContentModeBottom 18 | 19 | UIViewContentModeLeft 20 | 21 | UIViewContentModeRight 22 | 23 | UIViewContentModeTopLeft 24 | 25 | UIViewContentModeTopRight 26 | 27 | UIViewContentModeBottomLeft 28 | 29 | UIViewContentModeBottomRight 30 | 31 | ```` 32 | 33 | ## 注意 34 | 35 | - 凡是没有带Scale的,当图片尺寸超过ImageView尺寸时,只有部分显示在ImageView中 36 | - UIViewContentModeScaleToFill属性会导致图片变形。UIViewContentModeScaleAspectFit会保证图片比例不变,而且全部显示在ImageView中,这意味着ImageView会有部分空白。UIViewContentModeScaleAspectFill也会证图片比例不变,但是是填充整个ImageView的,可能只有部分图片显示出来。 37 | -------------------------------------------------------------------------------- /1_UIKit/控件/UIScrollView使用技巧.md: -------------------------------------------------------------------------------- 1 | ## UIScrollView使用技巧 2 | 3 | 1:IndicatorInsets 4 | 5 | 指定滚动条在scrollerView中的位置 6 | 7 | 该属性设置为0时显示滚动条,设置为最大值时候不显示滚动条,当然也可以通过scrollView.showsVerticalScrollIndicator去设置 8 | 9 | 2:contentInset 这个能指定scroll可以滚动的高度或者是宽度 10 | 11 | 3:若遇到一个很长的页面,xib无法正常拖控件时,可以用scroll解决,步骤如下(以1000点为例): 12 | 13 | - 设置view第四栏的属性 size 改为freeform ,并将view高度改为实际页面的高度为1000 14 | - 设置scrollview的高度改为1000,IndicatorInsets和contentInset都为1000 15 | - 这个时候就可以看见页面本来不可编辑的位置,编辑控件 16 | - 发布时,只需要把scrollview的height改回到568就可以了 17 | 18 | ## 属性列表 19 | 20 | ````objc 21 | CGPoint contentOffSet 监控目前滚动的位置 22 | CGSize contentSize 滚动范围的大小 23 | UIEdgeInsets contentInset 视图在scrollView中的位置 24 | id 25 | delegate 设置协议 26 | BOOL directionalLockEnabled 指定控件是否只能在一个方向上滚动 27 | BOOL bounces 控制控件遇到边框是否反弹 28 | BOOL alwaysBounceVertical 控制垂直方向遇到边框是否反弹 29 | BOOL alwaysBounceHorizontal 控制水平方向遇到边框是否反弹 30 | BOOL pagingEnabled 控制控件是否整页翻动 31 | BOOL scrollEnabled 控制控件是否能滚动 32 | BOOL showsHorizontalScrollIndicator 控制是否显示水平方向的滚动条 33 | BOOL 34 | showsVerticalScrollIndicator 控制是否显示垂直方向的滚动条 35 | UIEdgeInsets scrollIndicatorInsets 指定滚动条在scrollerView中的位置 36 | UIScrollViewIndicatorStyle 37 | indicatorStyle 设定滚动条的样式 38 | float decelerationRate 改变scrollerView的减速点位置 39 | BOOL tracking 监控当前目标是否正在被跟踪 40 | BOOL dragging 监控当前目标是否正在被拖拽 41 | BOOL decelerating 监控当前目标是否正在减速 42 | BOOL delaysContentTouches 控制视图是否延时调用开始滚动的方法 43 | BOOL canCancelContentTouches 控制控件是否接触取消touch的事件 44 | float minimumZoomScale 缩小的最小比例 45 | float maximumZoomScale 放大的最大比例 46 | float zoomScale 设置变化比例 47 | BOOL bouncesZoom 控制缩放的时候是否会反弹 48 | BOOL zooming 判断控件的大小是否正在改变 49 | BOOL zoomBouncing 判断是否正在进行缩放反弹 50 | BOOL scrollsToTop 控制控件滚动到顶部 51 | ```` 52 | -------------------------------------------------------------------------------- /1_UIKit/控件/UISpiltViewController用法.md: -------------------------------------------------------------------------------- 1 | > SpiltViewController可以用在ios8 or later,是一个主从拆分视图结构,只在ipad和iphone6(6s)puls上可以使用。 2 | 3 | 详细介绍可以阅读这篇文章:[UISplit​View​Controller](http://nshipster.cn/uisplitviewcontroller/) 4 | 5 | 6 | 这里只总结几点: 7 | 8 | - 1:split view controller导航结构建立可以通过新建项目,选择 master details模板是最快捷的方式 9 | - 2:为什么details视图也需要加一个navigation controller? 10 | 如果不加的话,在从视图就不会有导航栏,会导致用户不清数这个是一个拆分视图,如果要触发主控制器,用户必须奇迹般的知道要去向右滑动。 11 | 12 | 当然也有一个方法可以解决它,就是使用displayModeButtonItem()方法在从视图导航栏左按钮添加一个调出主视图的按钮,方法如下: 13 | 14 | ````swift 15 | navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem() 16 | navigationItem.leftItemsSupplementBackButton = true 17 | ```` 18 | 19 | [demo](https://github.com/NatashaTheRobot/UISplitViewControllerDemo) -------------------------------------------------------------------------------- /1_UIKit/控件/UIViewController添加子controller控制.md: -------------------------------------------------------------------------------- 1 | ## UIViewController 添加子controller控制 2 | 3 | ````objc 4 | 5 | //初始化 6 | vc0 = [[SearchTableViewController alloc] init]; 7 | [self addChildViewController:vc0]; 8 | [self didMoveToParentViewController:vc0]; 9 | [self.subView addSubview:vc0.view]; 10 | currentVC = vc0; 11 | 12 | vc1 = [[DemoDLSildeViewController alloc] init]; 13 | [self addChildViewController:vc1]; 14 | 15 | vc2 = [[Mytest1 alloc] init]; 16 | [self addChildViewController:vc2]; 17 | 18 | vc3 = [[AFDome alloc] init]; 19 | [self addChildViewController:vc3]; 20 | 21 | //使用 22 | [self transitionFromViewController:currentVC toViewController:(vc1) duration:1.0 options:UIViewAnimationOptionAllowAnimatedContent animations:Nil completion:Nil]; 23 | [self didMoveToParentViewController:vc1]; 24 | [self.subView addSubview:vc1.view]; 25 | currentVC = vc1; 26 | 27 | ```` 28 | -------------------------------------------------------------------------------- /1_UIKit/控件/activityindactor的使用.md: -------------------------------------------------------------------------------- 1 | ```` objc 2 | 3 | if([self.activityIndiactor isAnimating]){ 4 | [self.activityIndiactor stopAnimating]; 5 | }else{ 6 | [self.activityIndiactor startAnimating]; 7 | 8 | } 9 | self.activityIndiactor.hidesWhenStopped = true; 10 | ```` 11 | 12 | -------------------------------------------------------------------------------- /1_UIKit/控件/controller导航/UINavigationController使用.md: -------------------------------------------------------------------------------- 1 | ## UINavigationController使用 2 | 3 | 4 | ````objc 5 | 6 | //初始化 7 | ViewController1 *rootVC = [[ViewController1 alloc]initWithNibName:@"ViewController1" bundle:nil]; 8 | UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:rootVC]; 9 | self.window.rootViewController = navigationController; 10 | 11 | //页面跳转 12 | modal :pushViewController 13 | normal:presentViewController 14 | 15 | [self.navigationController presentViewController:[[ModalViewController alloc]init] animated:(YES) completion:^(void){ }]; 16 | //passValue by using NSNotificationCenter 1:setp register Notification 17 | [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(backValue:) name:@"postback" object:nil]; 18 | // selector 19 | - (void)backValue:(NSDictionary *)dict { 20 | NSLog(@"%@",dict); 21 | } 22 | 23 | //jump back! 24 | - (IBAction)goback:(id)sender { 25 | 26 | [self dismissViewControllerAnimated:(YES) completion:^(void){ 27 | //NSLog(@"dismiss"); 28 | //回传值 29 | NSDictionary *dict = [NSDictionary dictionaryWithObject:@"liuyanwei" forKey:@"name"]; 30 | [[NSNotificationCenter defaultCenter] postNotificationName:@"postback" object:dict]; 31 | 32 | }]; 33 | } 34 | //jump to rootController 35 | [vc.navigationController popToRootViewControllerAnimated:YES]; 36 | 37 | //导航栏图标按钮组 38 | UIButton *leftbutton= [UIButton buttonWithType:UIButtonTypeSystem]; 39 | leftbutton.titleLabel.text = @"123"; 40 | leftbutton.backgroundColor = [UIColor redColor]; 41 | leftbutton.frame =CGRectMake(0, 0, 30, 30); 42 | //[leftbutton setImage:[UIImage imageNamed:@"nav_back"] forState:UIControlStateNormal]; 43 | //[leftbutton addTarget:self action:@selector(back:) forControlEvents:UIControlEventTouchUpInside]; 44 | UIBarButtonItem *leftButtonItem=[[UIBarButtonItem alloc] initWithCustomView:leftbutton]; 45 | self.navigationItem.leftBarButtonItem=leftButtonItem; 46 | 47 | self.navigationItem.rightBarButtonItem=nil; 48 | UIButton *rightbutton1=[[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)]; 49 | //[rightbutton1 setImage:[UIImage imageNamed:@"market_new"] forState:UIControlStateNormal]; 50 | rightbutton1.backgroundColor = [UIColor redColor]; 51 | [rightbutton1 addTarget:self action:@selector(rightTarget1:) forControlEvents:UIControlEventTouchUpInside]; 52 | UIBarButtonItem *rightButtonItem1=[[UIBarButtonItem alloc] initWithCustomView:rightbutton1]; 53 | UIButton *rightbutton2=[[UIButton alloc] initWithFrame:CGRectMake(0, 35, 30, 30)]; 54 | //[rightbutton2 setImage:[UIImage imageNamed:@"filterIcon"] forState:UIControlStateNormal]; 55 | rightbutton2.backgroundColor = [UIColor purpleColor]; 56 | [rightbutton2 addTarget:self action:@selector(rightTarget2:) forControlEvents:UIControlEventTouchUpInside]; 57 | UIBarButtonItem *rightButtonItem2=[[UIBarButtonItem alloc] initWithCustomView:rightbutton2]; 58 | self.navigationItem.rightBarButtonItems=@[rightButtonItem1, rightButtonItem2]; 59 | ```` 60 | -------------------------------------------------------------------------------- /1_UIKit/控件/controller导航/storyboard导航结构使用.md: -------------------------------------------------------------------------------- 1 | ## uitabbar + navigationController 2 | 3 | 4 | - 1)删除故事版中默认内容,添加一个uitabbarController 并设置为initial controller 5 | - 2) 将默认的controller删除,添加2个navigationController,按住control拖至uitabbercontroller建立relationship 6 | - 3) 在controller里面bar item 设置title和image,当前选中样式需要到代码里面设置, 7 | 例如:self.tabBarItem.selectedImage=[UIImage imageNamed:@"ts探索_sel"]; 8 | - 4)建立内容页与navigationController的relationship,用navigationController+control 拖至 内容页的controller 9 | 10 | - 5)若某页中不希望出现navigation 和 tabbar ,可以在controller中选择hide button bar on push 11 | 12 | 代码中设置隐藏:self.hidesBottomBarWhenPushed=YES; 13 | 14 | 这个方法要注意使用的位置,在跳转前的控制器中使用,也可以用xxx.hidesBottomBarWhenPushed针对特定控制器 15 | -------------------------------------------------------------------------------- /1_UIKit/控件/controller导航/tabbarNavition.md: -------------------------------------------------------------------------------- 1 | 2 | ````swift 3 | 4 | 5 | //初始化uitabbar 6 | UITabBarController *tabBarController = [[UITabBarController alloc]init]; 7 | ViewController1 *vc1 = [[ViewController1 alloc]init]; 8 | ViewController2 *vc2 = [[ViewController2 alloc]init]; 9 | ViewController3 *vc3 = [[ViewController3 alloc]initWithNibName:@"View" bundle:nil]; 10 | ViewController4 *vc4 = [[ViewController4 alloc]init]; 11 | ViewController5 *vc5 = [[ViewController5 alloc]init]; 12 | ViewController6 *vc6 = [[ViewController6 alloc]init]; 13 | tabBarController.viewControllers = [NSArray arrayWithObjects:vc1,vc2,vc3,vc4,vc5,vc6,nil]; 14 | //配置uitabbar按钮样式 15 | vc1.tabBarItem.title = @"1"; 16 | vc2.tabBarItem.title = @"2"; 17 | vc3.tabBarItem.title = @"3"; 18 | vc4.tabBarItem.title = @"4"; 19 | vc5.tabBarItem.title = @"5"; 20 | vc6.tabBarItem.title = @"6"; 21 | vc1.tabBarItem.image = [UIImage imageNamed:@"cbxx"]; 22 | vc2.tabBarItem.image = [UIImage imageNamed:@"clwz"]; 23 | vc3.tabBarItem.image = [UIImage imageNamed:@"gjjxx"]; 24 | vc4.tabBarItem.image = [UIImage imageNamed:@"hmxx"]; 25 | vc5.tabBarItem.image = [UIImage imageNamed:@"jsywz"]; 26 | vc6.tabBarItem.image = [UIImage imageNamed:@"rqxx"]; 27 | vc1.tabBarItem.selectedImage = [UIImage imageNamed:@"cbxx1"]; 28 | vc2.tabBarItem.selectedImage = [UIImage imageNamed:@"clwz1"]; 29 | vc3.tabBarItem.selectedImage = [UIImage imageNamed:@"gjjxx1"]; 30 | vc4.tabBarItem.selectedImage = [UIImage imageNamed:@"hmxx1"]; 31 | vc5.tabBarItem.selectedImage = [UIImage imageNamed:@"jsywz1"]; 32 | vc6.tabBarItem.selectedImage = [UIImage imageNamed:@"rqxx1"]; 33 | //配置badge徽章 34 | vc1.tabBarItem.badgeValue = @"10"; 35 | vc4.tabBarItem.badgeValue = @"hi"; 36 | //tabbar入栈 37 | self.self.window.rootViewController =tabBarController; 38 | 39 | 40 | ```` 41 | -------------------------------------------------------------------------------- /1_UIKit/控件/controller导航/tabbar和navigation混用.md: -------------------------------------------------------------------------------- 1 | ## tabbar和navigation混用 2 | 3 | ````objc 4 | 5 | //初始化uitabbar 6 | UITabBarController *tabBarController = [[UITabBarController alloc]init]; 7 | 8 | ViewController1 *vc1 = [[ViewController1 alloc]init]; 9 | UINavigationController *navc = [[UINavigationController alloc]initWithRootViewController:vc1]; 10 | ViewController2 *vc2 = [[ViewController2 alloc]init]; 11 | ViewController3 *vc3 = [[ViewController3 alloc]initWithNibName:@"View" bundle:nil]; 12 | ViewController4 *vc4 = [[ViewController4 alloc]init]; 13 | ViewController5 *vc5 = [[ViewController5 alloc]init]; 14 | ViewController6 *vc6 = [[ViewController6 alloc]init]; 15 | tabBarController.viewControllers = [NSArray arrayWithObjects:navc,vc2,vc3,vc4,vc5,vc6,nil]; 16 | //配置uitabbar按钮样式 17 | vc1.tabBarItem.title = @"1"; 18 | vc2.tabBarItem.title = @"2"; 19 | vc3.tabBarItem.title = @"3"; 20 | vc4.tabBarItem.title = @"4"; 21 | vc5.tabBarItem.title = @"5"; 22 | vc6.tabBarItem.title = @"6"; 23 | vc1.tabBarItem.image = [UIImage imageNamed:@"cbxx"]; 24 | vc2.tabBarItem.image = [UIImage imageNamed:@"clwz"]; 25 | vc3.tabBarItem.image = [UIImage imageNamed:@"gjjxx"]; 26 | vc4.tabBarItem.image = [UIImage imageNamed:@"hmxx"]; 27 | vc5.tabBarItem.image = [UIImage imageNamed:@"jsywz"]; 28 | vc6.tabBarItem.image = [UIImage imageNamed:@"rqxx"]; 29 | vc1.tabBarItem.selectedImage = [UIImage imageNamed:@"cbxx1"]; 30 | vc2.tabBarItem.selectedImage = [UIImage imageNamed:@"clwz1"]; 31 | vc3.tabBarItem.selectedImage = [UIImage imageNamed:@"gjjxx1"]; 32 | vc4.tabBarItem.selectedImage = [UIImage imageNamed:@"hmxx1"]; 33 | vc5.tabBarItem.selectedImage = [UIImage imageNamed:@"jsywz1"]; 34 | vc6.tabBarItem.selectedImage = [UIImage imageNamed:@"rqxx1"]; 35 | //配置badge徽章 36 | vc1.tabBarItem.badgeValue = @"10"; 37 | vc4.tabBarItem.badgeValue = @"hi"; 38 | //tabbar入栈 39 | self.self.window.rootViewController =tabBarController; 40 | ```` 41 | -------------------------------------------------------------------------------- /1_UIKit/控件/controller导航/页面跳转和传值.md: -------------------------------------------------------------------------------- 1 | ## 页面跳转 2 | 3 | ````objc 4 | //页面跳转和传值 5 | self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]]; 6 | NSLog(@"%@",[[UIScreen mainScreen] bounds]); 7 | self.window.backgroundColor = [UIColor redColor]; 8 | self.vc = [[BaseTableViewController alloc] initWithNibName:@"BaseTableViewController" bundle:nil]; 9 | self.window.rootViewController = self.vc; 10 | [self.window makeKeyAndVisible]; 11 | 12 | ```` 13 | 14 | ````swift 15 | 16 | //故事板跳转 17 | UIStoryboard *story = [UIStoryboard storyboardWithName:@"填写故事板名称" bundle:nil]; 18 | UIViewController *vc = [story instantiateViewControllerWithIdentifier:@"填写ViewController在故事板中设置的identifier"]; 19 | [self.navigationController pushViewController:vc animated:YES]; 20 | ```` 21 | 22 | ````objc 23 | //UINavigationController使用 24 | ViewController1 *rootVC = [[ViewController1 alloc]initWithNibName:@"ViewController1" bundle:nil]; 25 | UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:rootVC]; 26 | self.window.rootViewController = navigationController; 27 | ```` 28 | 29 | 30 | ## 通知传值 31 | 32 | ````objc 33 | 34 | //modal视图跳转 --附带数据传输 35 | //jump 36 | ------------------------------------------------------------------------------------------------------------------------------ 37 | UIViewController *vc = [UIViewController alloc]init]; 38 | UINavigationController *navc = [[UINavigationController alloc]initWithRootViewController:vc]; 39 | [self.navigationController presentViewController:navc animated:YES completion:^{ 40 | [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(backValue:) name:@"postback" object:nil]; 41 | 42 | }]; 43 | 44 | 45 | - (void)backValue:(NSNotification *)notif { 46 | NSLog(@"%@",notif.userInfo); 47 | NSLog(@"%@",notif.object); 48 | } 49 | 50 | //jump back! 51 | - (IBAction)goback:(id)sender { 52 | 53 | [self dismissViewControllerAnimated:(YES) completion:^(void){ 54 | //NSLog(@"dismiss"); 55 | //回传值 56 | NSDictionary *dict = [NSDictionary dictionaryWithObject:@"liuyanwei" forKey:@"name"]; 57 | [[NSNotificationCenter defaultCenter]postNotificationName:@"postback" object:nil userInfo:dict]; 58 | }]; 59 | } 60 | 61 | ```` 62 | 63 | ## 委托传值 64 | 65 | ````objc 66 | 67 | 1:先定义委托 68 | //绑定数据回叫委托 69 | @protocol passDataDelegate 70 | -(void)passValue:(NSString *)value; 71 | @end 72 | 73 | 2:主页面实现委托和方法 74 | 委托: 75 | @interface MainViewController : UIViewController 76 | 方法: 77 | -(void)passValue:(NSString *)value{ 78 | NSLog(@"%@",value); 79 | } 80 | 81 | 3:主页面跳转到获取值的页面 82 | //页面跳转 83 | FetchValueViewController *vc = [[FetchValueViewController alloc]init]; 84 | vc.passDataDelegate = self; 85 | [self.navigationController presentViewController:vc animated:YES completion:nil]; 86 | 87 | 88 | 4:FetchValueViewController.h添加一个委托的属性 89 | @property (nonatomic,assign) NSObject *delegate; 90 | 91 | 5:FetchValueViewController.m将值回传 92 | [delegate passValue:@"回传的值"]; 93 | 调用过这个方法后,会进入到MainViewController委托的实现方法passValue里。 94 | 95 | 96 | ) 97 | ```` 98 | 99 | ## 属性传值,这个不说了,太简单了 100 | -------------------------------------------------------------------------------- /1_UIKit/控件/ios获取系统信息.md: -------------------------------------------------------------------------------- 1 | 2 | ## app版本号 3 | 4 | ````objc 5 | +(NSString *)appVersion{ 6 | 7 | NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; 8 | // NSString *name = [infoDictionary objectForKey:@"CFBundleDisplayName"]; 9 | NSString *version = [infoDictionary objectForKey:@"CFBundleShortVersionString"]; 10 | // NSString *build = [infoDictionary objectForKey:@"CFBundleVersion"]; 11 | // NSString *label = [NSString stringWithFormat:@"%@ v%@ (build %@)", name, version, build]; 12 | 13 | return version; 14 | } 15 | @end 16 | 17 | ```` 18 | 19 | 20 | ## 其他信息 21 | 22 | ````objc 23 | 24 | NSString* identifierNumber = [[UIDevice currentDevice] uniqueIdentifier]; 25 | NSLog(@"手机序列号: %@",identifierNumber); 26 | //手机别名: 用户定义的名称 27 | NSString* userPhoneName = [[UIDevice currentDevice] name]; 28 | NSLog(@"手机别名: %@", userPhoneName); 29 | //设备名称 30 | NSString* deviceName = [[UIDevice currentDevice] systemName]; 31 | NSLog(@"设备名称: %@",deviceName ); 32 | //手机系统版本 33 | NSString* phoneVersion = [[UIDevice currentDevice] systemVersion]; 34 | NSLog(@"手机系统版本: %@", phoneVersion); 35 | //手机型号 36 | NSString* phoneModel = [[UIDevice currentDevice] model]; 37 | NSLog(@"手机型号: %@",phoneModel ); 38 | //地方型号 (国际化区域名称) 39 | NSString* localPhoneModel = [[UIDevice currentDevice] localizedModel]; 40 | NSLog(@"国际化区域名称: %@",localPhoneModel ); 41 | 42 | NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; 43 | // 当前应用名称 44 | NSString *appCurName = [infoDictionary objectForKey:@"CFBundleDisplayName"]; 45 | NSLog(@"当前应用名称:%@",appCurName); 46 | // 当前应用软件版本 比如:1.0.1 47 | NSString *appCurVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"]; 48 | NSLog(@"当前应用软件版本:%@",appCurVersion); 49 | // 当前应用版本号码 int类型 50 | NSString *appCurVersionNum = [infoDictionary objectForKey:@"CFBundleVersion"]; 51 | NSLog(@"当前应用版本号码:%@",appCurVersionNum); 52 | 53 | //手机序列号 54 | NSString* identifierNumber = [[UIDevice currentDevice] uniqueIdentifier]; 55 | NSLog(@"手机序列号: %@",identifierNumber); 56 | //手机别名: 用户定义的名称 57 | NSString* userPhoneName = [[UIDevice currentDevice] name]; 58 | NSLog(@"手机别名: %@", userPhoneName); 59 | //设备名称 60 | NSString* deviceName = [[UIDevice currentDevice] systemName]; 61 | NSLog(@"设备名称: %@",deviceName ); 62 | //手机系统版本 63 | NSString* phoneVersion = [[UIDevice currentDevice] systemVersion]; 64 | NSLog(@"手机系统版本: %@", phoneVersion); 65 | //手机型号 66 | NSString* phoneModel = [[UIDevice currentDevice] model]; 67 | NSLog(@"手机型号: %@",phoneModel ); 68 | //地方型号 (国际化区域名称) 69 | NSString* localPhoneModel = [[UIDevice currentDevice] localizedModel]; 70 | NSLog(@"国际化区域名称: %@",localPhoneModel ); 71 | 72 | NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; 73 | // 当前应用名称 74 | NSString *appCurName = [infoDictionary objectForKey:@"CFBundleDisplayName"]; 75 | NSLog(@"当前应用名称:%@",appCurName); 76 | // 当前应用软件版本 比如:1.0.1 77 | NSString *appCurVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"]; 78 | NSLog(@"当前应用软件版本:%@",appCurVersion); 79 | // 当前应用版本号码 int类型 80 | NSString *appCurVersionNum = [infoDictionary objectForKey:@"CFBundleVersion"]; 81 | NSLog(@"当前应用版本号码:%@",appCurVersionNum); 82 | 83 | ```` 84 | -------------------------------------------------------------------------------- /1_UIKit/控件/tableview/MyTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyTableViewController.h 3 | // LearningTableView 4 | // 5 | // Created by 刘彦玮 on 15/2/8. 6 | // Copyright (c) 2015年 刘彦玮. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MyTableViewController : UITableViewController 12 | 13 | @property NSArray *data ; 14 | @property NSArray *flilterData ; 15 | @property UITableViewCell *cell; 16 | @property (weak, nonatomic) IBOutlet UISearchBar *searchBar; 17 | 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /1_UIKit/控件/tableview/MyTableViewController.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // MyTableViewController.m 4 | // LearningTableView 5 | // 6 | // Created by 刘彦玮 on 15/2/8. 7 | // Copyright (c) 2015年 刘彦玮. All rights reserved. 8 | // 9 | 10 | #import "MyTableViewController.h" 11 | #import "TableViewCell1.h" 12 | 13 | @interface MyTableViewController () 14 | 15 | @end 16 | 17 | @implementation MyTableViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | self.data = [[NSArray alloc] initWithObjects:@"hehe",@"asda",@"cvd",@"wqew",@"ggfd",@"bgjw",@"adsad",nil]; 22 | self.view.frame = CGRectMake(0, 20, 320, 516); 23 | self.flilterData = [NSArray arrayWithArray:self.data]; 24 | 25 | self.tableView.contentOffset = CGPointMake(0, -50); 26 | } 27 | 28 | - (void)didReceiveMemoryWarning { 29 | [super didReceiveMemoryWarning]; 30 | // Dispose of any resources that can be recreated. 31 | } 32 | 33 | #pragma mark - Table view data source 34 | 35 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 36 | #warning Potentially incomplete method implementation. 37 | // Return the number of sections. 38 | return 1; 39 | } 40 | 41 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 42 | #warning Incomplete method implementation. 43 | // Return the number of rows in the section. 44 | return self.flilterData.count; 45 | } 46 | 47 | 48 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 49 | 50 | static NSString *tableCellIdentifier = @"name"; 51 | TableViewCell1 *cell = (TableViewCell1 *)[tableView dequeueReusableCellWithIdentifier:tableCellIdentifier]; 52 | if(cell == nil){ 53 | NSArray *nib = [[NSBundle mainBundle]loadNibNamed:@"TableViewCell1" owner:self options:nil]; 54 | for(id oneObject in nib){ 55 | if([oneObject isKindOfClass:[TableViewCell1 class]]){ 56 | cell = (TableViewCell1 *)oneObject; 57 | } 58 | } 59 | } 60 | cell.lable1.text = [self.flilterData objectAtIndex:indexPath.row]; 61 | return cell; 62 | } 63 | 64 | 65 | /* 66 | // Override to support conditional editing of the table view. 67 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 68 | // Return NO if you do not want the specified item to be editable. 69 | return YES; 70 | } 71 | */ 72 | 73 | /* 74 | // Override to support editing the table view. 75 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 76 | if (editingStyle == UITableViewCellEditingStyleDelete) { 77 | // Delete the row from the data source 78 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 79 | } else if (editingStyle == UITableViewCellEditingStyleInsert) { 80 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 81 | } 82 | } 83 | */ 84 | 85 | /* 86 | // Override to support rearranging the table view. 87 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { 88 | } 89 | */ 90 | 91 | /* 92 | // Override to support conditional rearranging of the table view. 93 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 94 | // Return NO if you do not want the item to be re-orderable. 95 | return YES; 96 | } 97 | */ 98 | 99 | /* 100 | #pragma mark - Table view delegate 101 | 102 | // In a xib-based application, navigation from a table can be handled in -tableView:didSelectRowAtIndexPath: 103 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 104 | // Navigation logic may go here, for example: 105 | // Create the next view controller. 106 | <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:<#@"Nib name"#> bundle:nil]; 107 | 108 | // Pass the selected object to the new view controller. 109 | 110 | // Push the view controller. 111 | [self.navigationController pushViewController:detailViewController animated:YES]; 112 | } 113 | */ 114 | 115 | /* 116 | #pragma mark - Navigation 117 | 118 | // In a storyboard-based application, you will often want to do a little preparation before navigation 119 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 120 | // Get the new view controller using [segue destinationViewController]. 121 | // Pass the selected object to the new view controller. 122 | } 123 | */ 124 | 125 | #pragma mark 搜索查询 126 | -(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ 127 | // NSLog(@"%@",searchBar.text); 128 | } 129 | -(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ 130 | NSLog(@"%@",searchBar.text); 131 | [self filterContentForSearchbar:searchText]; 132 | } 133 | 134 | -(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{ 135 | 136 | NSLog(@"cancel"); 137 | 138 | } 139 | 140 | -(void)filterContentForSearchbar:(NSString *)searchText{ 141 | if([searchText length]==0){ 142 | //查询所有 143 | self.flilterData = [NSArray arrayWithArray:self.data]; 144 | } 145 | else{ 146 | 147 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@",searchText]; 148 | self.flilterData = [self.flilterData filteredArrayUsingPredicate:predicate]; 149 | 150 | 151 | } 152 | } 153 | 154 | #pragma mark 索引列表 155 | - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView 156 | { 157 | //set color 158 | tableView.sectionIndexColor = [UIColor redColor]; 159 | tableView.sectionIndexBackgroundColor = [UIColor clearColor]; 160 | 161 | NSMutableArray *toBeReturned = [[NSMutableArray alloc]init]; 162 | for(char c = 'A';c<='Z';c++) 163 | 164 | [toBeReturned addObject:[NSString stringWithFormat:@"%c",c]]; 165 | 166 | return toBeReturned; 167 | 168 | } 169 | - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index 170 | { 171 | // [tableView setContentOffset:CGPointMake(0,41*(count-1)-20) animated:YES]; 172 | return 5; 173 | 174 | } 175 | @end 176 | -------------------------------------------------------------------------------- /1_UIKit/控件/tableview/MyTableViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /1_UIKit/控件/tableview/UISearchController用法.md: -------------------------------------------------------------------------------- 1 | ## UISearchController用法 2 | 3 | > UISearchController和UISearchBar的区别,一个是全屏搜索,一个是搜索框搜索。 4 | 5 | 6 | ### 在含有UITableView的controller中使用UISearchController 7 | 8 | ````objc 9 | 10 | - .h文件声明: 11 | @property (strong, nonatomic) IBOutlet UITableView *tableView; 12 | @property (nonatomic, strong) UISearchController *searchController; 13 | 使用委托UISearchResultsUpdating 14 | 页面中添加UITableView 15 | 16 | ```` 17 | 18 | ````objc 19 | 20 | - .m文件 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | // Do any additional setup after loading the view. 25 | self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; 26 | self.searchController.searchResultsUpdater = self; 27 | [self.searchController.searchBar sizeToFit]; 28 | self.tableView.tableHeaderView = self.searchController.searchBar; 29 | self.definesPresentationContext = YES; 30 | 31 | } 32 | 33 | 实现UISearchResultsUpdating 委托方法 34 | #pragma mark - UISearchResultsUpdating 35 | - (void)updateSearchResultsForSearchController:(UISearchController *)searchController { 36 | NSLog(@"Entering:%@",searchController.searchBar.text); 37 | } 38 | 39 | ```` 40 | -------------------------------------------------------------------------------- /1_UIKit/控件/tableview/tableview基本用法.md: -------------------------------------------------------------------------------- 1 | ## table基本用法 2 | 3 | 4 | ````objc 5 | 6 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 7 | 8 | // Return the number of sections. 9 | return 1; 10 | } 11 | 12 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 13 | 14 | // Return the number of rows in the section. 15 | return data.count; 16 | 17 | } 18 | //行高度 19 | -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 20 | { 21 | //动态控制cell的高度 22 | //UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; 23 | //return cell.frame.size.height; 24 | 25 | return 120; 26 | } 27 | 28 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 29 | 30 | NSString *cellIdentifier = @"cell"; 31 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 32 | if (cell == nil) 33 | { 34 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; 35 | } 36 | //#import 37 | [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.jjmc.com.cn/images/navi_figure_03.png"] 38 | placeholderImage:[UIImage imageNamed:@"goodsHot"]];//左侧图片 39 | //配置cell样式 40 | cell.textLabel.text = [self.data objectAtIndex:[indexPath row]];//主标题 41 | cell.detailTextLabel.text = @"detailslable";//副标题 42 | //cell.imageView.image = [UIImage imageNamed:@"goodsHot"];//左侧图片 43 | cell.accessoryView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"goodsHot"]];//右侧图片 44 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 45 | return cell; 46 | 47 | } 48 | 49 | ```` 50 | 51 | ## 自定义UITableViewCell有两种方法: 52 | 53 | 1:利用xib 54 | 55 | ````objc 56 | 57 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 58 | 59 | static NSString *cellIdentifier=@"name"; 60 | BOOL nibsRegistered=NO; 61 | if (!nibsRegistered) { 62 | UINib *nib=[UINib nibWithNibName:@"TableViewCell1" bundle:nil]; 63 | [tableView registerNib:nib forCellReuseIdentifier:cellIdentifier]; 64 | nibsRegistered=YES; 65 | } 66 | TableViewCell1 *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 67 | //cell 上的元素初始化代码 68 | return cell; 69 | } 70 | 71 | ```` 72 | 73 | 2:使用NSBundle 74 | 75 | 76 | ````objc 77 | 78 | static NSString *tableCellIdentifier = @"name"; 79 | TableViewCell1 *cell = (TableViewCell1 *)[tableView dequeueReusableCellWithIdentifier:tableCellIdentifier]; 80 | if(cell == nil){ 81 | NSArray *nib = [[NSBundle mainBundle]loadNibNamed:@"TableViewCell1" owner:self options:nil]; 82 | for(id oneObject in nib){ 83 | if([oneObject isKindOfClass:[TableViewCell1 class]]){ 84 | cell = (TableViewCell1 *)oneObject; 85 | } 86 | } 87 | } 88 | cell.lable1.text = [self.data objectAtIndex:indexPath.row]; 89 | return cell; 90 | 91 | 2.1:无nib文件 92 | static NSString *CellIdentifier = @"Cell"; 93 | 94 | PostTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 95 | if (!cell) { 96 | cell = [[PostTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 97 | } 98 | 99 | cell.post = [self.posts objectAtIndex:(NSUInteger)indexPath.row]; 100 | 101 | return cell; 102 | 103 | //initWithStyle 方法 104 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 105 | if (!self) { 106 | return nil; 107 | } 108 | ```` 109 | 110 | 111 | 112 | 3:使用故事版 (注意1:设置Identifier2:设置prototype cell 1 3:配置cell的class) 113 | 114 | 115 | ````objc 116 | 117 | 1 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 118 | 2 { 119 | 3 //这个是在storyboard中设置的identifier 120 | 4 static NSString *tableCellIdentifier = @"name"; 121 | 5 MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:tableCellIdentifier]; 122 | 6 //cell初始化 123 | 7 return cell; 124 | 8 } 125 | 126 | 127 | 128 | 129 | #pragma mark - Table view data source 130 | 131 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 132 | #warning Potentially incomplete method implementation. 133 | // Return the number of sections. 134 | return 1; 135 | } 136 | 137 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 138 | #warning Incomplete method implementation. 139 | // Return the number of rows in the section. 140 | return self.flilterData.count; 141 | } 142 | 143 | 144 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 145 | 146 | static NSString *tableCellIdentifier = @"name"; 147 | TableViewCell1 *cell = (TableViewCell1 *)[tableView dequeueReusableCellWithIdentifier:tableCellIdentifier]; 148 | if(cell == nil){ 149 | NSArray *nib = [[NSBundle mainBundle]loadNibNamed:@"TableViewCell1" owner:self options:nil]; 150 | for(id oneObject in nib){ 151 | if([oneObject isKindOfClass:[TableViewCell1 class]]){ 152 | cell = (TableViewCell1 *)oneObject; 153 | } 154 | } 155 | } 156 | cell.lable1.text = [self.flilterData objectAtIndex:indexPath.row]; 157 | return cell; 158 | } 159 | 160 | ```` 161 | 162 | 163 | ## 搜索查询 164 | 165 | ````objc 166 | 167 | -(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ 168 | 169 | // NSLog(@"%@",searchBar.text); 170 | } 171 | -(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ 172 | NSLog(@"%@",searchBar.text); 173 | [self filterContentForSearchbar:searchText]; 174 | } 175 | 176 | -(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{ 177 | 178 | NSLog(@"cancel"); 179 | 180 | } 181 | 182 | -(void)filterContentForSearchbar:(NSString *)searchText{ 183 | if([searchText length]==0){ 184 | //查询所有 185 | self.flilterData = [NSArray arrayWithArray:self.data]; 186 | } 187 | else{ 188 | 189 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@",searchText]; 190 | self.flilterData = [self.flilterData filteredArrayUsingPredicate:predicate]; 191 | 192 | 193 | } 194 | } 195 | 196 | #pragma mark 索引列表 197 | - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView 198 | { 199 | //set color 200 | tableView.sectionIndexColor = [UIColor redColor]; 201 | tableView.sectionIndexBackgroundColor = [UIColor clearColor]; 202 | 203 | NSMutableArray *toBeReturned = [[NSMutableArray alloc]init]; 204 | for(char c = 'A';c<='Z';c++) 205 | 206 | [toBeReturned addObject:[NSString stringWithFormat:@"%c",c]]; 207 | 208 | return toBeReturned; 209 | 210 | } 211 | - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index 212 | { 213 | // [tableView setContentOffset:CGPointMake(0,41*(count-1)-20) animated:YES]; 214 | return 5; 215 | 216 | } 217 | 218 | 219 | ```` 220 | 221 | 222 | ## ios6 以后的新用法 223 | 224 | 225 | 旧的方法 226 | 227 | ````objc 228 | 229 | static NSString *ID = @"cell"; 230 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 231 | if (cell == nil) { 232 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 233 | } 234 | 235 | ```` 236 | 237 | 新方法可以这样用 238 | 239 | ````objc 240 | static NSString *ID = @"cell"; 241 | [self.tableView registerClass:[MyCell class] forCellReuseIdentifier:ID]; 242 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID forIndexPath:indexPath]; 243 | 244 | ```` 245 | 246 | 区别在于之前的写法取出重用cell的时候可能是空的 247 | 而后来的写法如果取出空的那就自动创建一个新的 register就是告诉它创建个什么样的 248 | 249 | -------------------------------------------------------------------------------- /1_UIKit/控件/tableview/tableview常见问题.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 为什么顶部会留言一段空白,如何处理 4 | self.automaticallyAdjustsScrollViewInsets = NO; 5 | 6 | 7 | ## 去除点击样式 8 | 9 | ````objc 10 | 11 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 12 | 13 | { 14 | 15 | // UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 16 | 17 | // [cell setSelectionStyle: ]; (这种是没有点击后的阴影效果) 18 | 19 | } 20 | 21 | ```` 22 | -------------------------------------------------------------------------------- /1_UIKit/控件/view强制横屏_支持arc.md: -------------------------------------------------------------------------------- 1 | 2 | ## 方法一:转为横屏模式 3 | 4 | ````objc 5 | //强制横屏 6 | if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) { 7 | SEL selector = NSSelectorFromString(@"setOrientation:"); 8 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]]; 9 | [invocation setSelector:selector]; 10 | [invocation setTarget:[UIDevice currentDevice]]; 11 | int val = UIInterfaceOrientationLandscapeRight; 12 | [invocation setArgument:&val atIndex:2]; 13 | [invocation invoke]; 14 | } 15 | 16 | ```` 17 | 18 | 19 | 20 | ## 方法二:旋转uiview 21 | 22 | ````objc 23 | 24 | - (void)deviceOrientationDidChange: (NSNotification *)notification 25 | 26 | { 27 | 28 | UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 29 | CGFloat startRotation = [[self valueForKeyPath:@"layer.transform.rotation.z"] floatValue]; 30 | CGAffineTransform rotation; 31 | switch (interfaceOrientation) { 32 | case UIInterfaceOrientationLandscapeLeft: 33 | rotation = CGAffineTransformMakeRotation(-startRotation + M_PI * 270.0 / 180.0); 34 | break; 35 | case UIInterfaceOrientationLandscapeRight: 36 | rotation = CGAffineTransformMakeRotation(-startRotation + M_PI * 90.0 / 180.0); 37 | break; 38 | case UIInterfaceOrientationPortraitUpsideDown: 39 | rotation = CGAffineTransformMakeRotation(-startRotation + M_PI * 180.0 / 180.0); 40 | break; 41 | default: 42 | rotation = CGAffineTransformMakeRotation(-startRotation + 0.0); 43 | break; 44 | } 45 | view.transform = rotation; 46 | } 47 | 48 | ```` 49 | 50 | -------------------------------------------------------------------------------- /1_UIKit/控件/修改searchBar的cancel文字.md: -------------------------------------------------------------------------------- 1 | ## 修改SearchBar的Cancel Button 的Title 2 | 3 | 4 | ````objc 5 | // 注意点: 6 | // 使用iOS8 SDK ,本次 UISearchBar适用于iOS7(+)版本,如果想要适配iOS6,则需要对应适配iOS6. 7 | // 例如: 8 | // iOS7+ : for(id cc in [searchBar.subviews[0] subviews]){} 9 | // iOS7- : for(id cc in [searchBar subviews]){} 10 | // 11 | ///#end 12 | 13 | - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar 14 | { 15 | for(id cc in [searchBar.subviews[0] subviews]) 16 | { 17 | if([cc isKindOfClass:[UIButton class]]) 18 | { 19 | UIButton *btn = (UIButton *)cc; 20 | [btn setTitle:[AppLanguageProcess getLanguageWithKey:@"TEXT_CANCEL"] forState:UIControlStateNormal]; 21 | [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 22 | } 23 | } 24 | } 25 | 26 | ```` 27 | -------------------------------------------------------------------------------- /1_UIKit/控件/打电话、发短信、email.md: -------------------------------------------------------------------------------- 1 | ## 打电话、发短信、email 2 | 3 | ````objc 4 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://13851488992"]]; //sms 5 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://13851488992"]]; //tel 6 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto:coolnameismy@sina.com"]]; //email 7 | ```` 8 | -------------------------------------------------------------------------------- /1_UIKit/控件/照相功能的使用.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 使用前 4 | 5 | 1定义actionSheet选择照片获取方式,一般有相册获取和拍照获取两种方式 6 | 2定义actionSheet对象和委托 7 | 8 | ````objc 9 | 10 | @property (strong,nonatomic) UIActionSheet *actionSheet;//对象 11 | //委托 12 | _actionSheet = [[UIActionSheet alloc]initWithTitle:@"选择获取方式" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"打开照相机",@"从相册中选择", nil]; 13 | 14 | ```` 15 | ## action事件处理 16 | 17 | ````objc 18 | 19 | //actionSheet delegate 20 | - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ 21 | switch (buttonIndex) { 22 | case 0: 23 | [self takePhoto]; 24 | break; 25 | case 1: 26 | [self LocalPhoto]; 27 | break; 28 | default: 29 | break; 30 | } 31 | 32 | } 33 | - (void)actionSheetCancel:(UIActionSheet *)actionSheet{ 34 | NSLog(@"actionSheetCancel"); 35 | } 36 | 37 | ```` 38 | 39 | 40 | ## 使用时:启动相册和照相机的方法 41 | 42 | `````objc 43 | //开始拍照 44 | -(void)takePhoto 45 | { 46 | UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera; 47 | if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) 48 | { 49 | self.imagePicker = [[UIImagePickerController alloc] init]; 50 | self.imagePicker.delegate = self; 51 | //设置拍照后的图片可被编辑 52 | self.imagePicker.allowsEditing = YES; 53 | self.imagePicker.sourceType = sourceType; 54 | [self presentViewController:_imagePicker animated:YES completion:nil]; 55 | }else 56 | { 57 | NSLog(@"模拟其中无法打开照相机,请在真机中使用"); 58 | } 59 | } 60 | 61 | //打开本地相册 62 | -(void)LocalPhoto 63 | { 64 | 65 | self.imagePicker = [[UIImagePickerController alloc] init]; 66 | self.imagePicker.delegate = self; 67 | 68 | //设置选择后的图片可被编辑 69 | _imagePicker.allowsEditing = YES; 70 | [self presentViewController:_imagePicker animated:YES completion:nil]; 71 | 72 | 73 | } 74 | 75 | ```` 76 | ## 使用后:设置选择后的委托事件,获取图片,并处理业务逻辑 77 | 78 | ````objc 79 | 声明委托 并实现方法 80 | 声明对象@property (nonatomic, strong) UIImagePickerController *imagePicker; 81 | 82 | 83 | //相册选择 84 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ 85 | NSLog(@"imagePickerController"); 86 | //获取照片数 87 | UIImage* image = [info objectForKey: @"UIImagePickerControllerEditedImage"]; 88 | self.headportrait.image = image; 89 | 90 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 91 | if([picker respondsToSelector:@selector(dismissModalViewControllerAnimated:)]){ 92 | [picker dismissModalViewControllerAnimated:YES completion:nil]; 93 | } 94 | else 95 | #endif 96 | { 97 | [picker dismissViewControllerAnimated:YES completion:nil]; 98 | } 99 | 100 | } 101 | - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ 102 | NSLog(@"imagePickerControllerDidCancel"); 103 | 104 | imagePickerControllerDidCancel#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 105 | if([picker respondsToSelector:@selector(dismissModalViewControllerAnimated:)]){ 106 | [picker dismissModalViewControllerAnimated:YES completion:nil]; 107 | } 108 | else 109 | #endif 110 | { 111 | [picker dismissViewControllerAnimated:YES completion:nil]; 112 | } 113 | } 114 | ```` 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /1_UIKit/控件/警告控件使用.md: -------------------------------------------------------------------------------- 1 | ## alertview使用 2 | ````objc 3 | //显示alert提示 4 | -(void)alert:(NSString *)msg{ 5 | UIAlertView* alert = [[UIAlertView alloc]initWithTitle:@"messaeg" message:msg delegate:nil cancelButtonTitle:@"确认" otherButtonTitles:@"取消", nil]; 6 | [alert show]; 7 | } 8 | 9 | ```` 10 | 11 | ## actionsheet使用 12 | 13 | ````objc 14 | 15 | 1:继承委托 16 | UIActionSheetDelegate 17 | 2:实现 18 | -(void)showActionSheet:(UIView *) view{ 19 | UIActionSheet *sheet = [[UIActionSheet alloc]initWithTitle:@"title" delegate:self cancelButtonTitle:@"canbutton" destructiveButtonTitle:@"破坏性按钮" otherButtonTitles:@"sina",@"tengxun" ,nil]; 20 | sheet.actionSheetStyle = UIActionSheetStyleAutomatic; 21 | [sheet showInView:view]; 22 | 23 | } 24 | - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex 25 | { 26 | NSLog(@"click sheet at index : %li",(long)buttonIndex); 27 | } 28 | 29 | ```` 30 | 31 | 32 | ## swift 33 | 34 | 35 | ````swift 36 | 37 | import UIKit 38 | import Foundation 39 | 40 | public class Common: NSObject,UIActionSheetDelegate { 41 | 42 | 43 | public func showSheet(view:UIView){ 44 | var sheet:UIActionSheet = UIActionSheet(title: nil, delegate: self, cancelButtonTitle: "cancel", destructiveButtonTitle: "breakbutton", otherButtonTitles: "other1","other2"); 45 | sheet.actionSheetStyle = UIActionSheetStyle.BlackTranslucent; 46 | sheet.showInView(view); 47 | 48 | 49 | } 50 | public func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) 51 | { 52 | NSLog("click in index ;%d", buttonIndex); 53 | } 54 | 55 | } 56 | 57 | ```` 58 | -------------------------------------------------------------------------------- /1_UIKit/控件/进度条和定时器的使用.md: -------------------------------------------------------------------------------- 1 | ## 进度条和定时器的使用 2 | 3 | ````objc 4 | 5 | @implementation MainController 6 | 7 | - (void)viewDidLoad { 8 | [super viewDidLoad]; 9 | //[self showScreenInfo]; 10 | 11 | 12 | //定时器的使用 13 | timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(download) userInfo:nil repeats:YES]; 14 | 15 | 16 | 17 | } 18 | 19 | -(void)download{ 20 | self.myprogress.progress = self.myprogress.progress+0.1; 21 | if(self.myprogress.progress ==1){ 22 | [timer invalidate]; 23 | [self alert:@"下载完成"]; 24 | } 25 | 26 | } 27 | @end 28 | ```` 29 | -------------------------------------------------------------------------------- /1_UIKit/控件/键盘出现和隐藏.md: -------------------------------------------------------------------------------- 1 | ## 键盘的使用 2 | 3 | ````objc 4 | 5 | 1:键盘打开和关闭通知 6 | //注册键盘关闭打开事件 UIKeyboardWillShowNotification 7 | [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(whenKeyboardShow:) name:UIKeyboardWillShowNotification object:nil]; 8 | [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(whenKeyboardHide:) name:UIKeyboardWillHideNotification object:nil]; 9 | 10 | ------------------------------------------------------------------ 11 | 2:点击键盘reture让键盘消失 12 | //注册键盘按键委托 13 | // 14 | self.textField.delegate = self; 15 | -(BOOL)textFieldShouldReturn:(UITextField *)textField{ 16 | [self KeyDismiss]; 17 | return true; 18 | } 19 | //让键盘消失 20 | -(void)KeyDismiss{ 21 | [self.textField resignFirstResponder]; 22 | } 23 | -------------------------------------------------------------------------------------------------------------- 24 | 3:点击view让键盘消失 25 | //注册view点击后隐藏键盘 26 | [self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:(self) action:@selector(KeyDismiss)]]; 27 | 28 | 4:键盘出现和隐藏时文本框的和scroll滚动 29 | -(void)whenKeyboardHide:(NSNotification*) notif{ 30 | //获取当前键盘高度 31 | NSDictionary* info = notif.userInfo; 32 | NSValue* value = [info objectForKey:UIKeyboardFrameEndUserInfoKey]; 33 | CGRect keyboardRect = [value CGRectValue]; 34 | //重设scrollview高度 35 | [UIView animateWithDuration:0.2f animations:^{ 36 | [self.scrollView setContentOffset:CGPointMake(0,self.prevY-keyboardRect.size.height)]; 37 | [self.textField setFrame:CGRectMake(0,538,320,30)]; 38 | }]; 39 | //若没有scrollview可以使用uiview位移 40 | //CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0.0, -keyboardRect.size.height/2); 41 | //[_txt_email setTransform:myTransform]; 42 | //[_txt_pwd setTransform:myTransform]; 43 | } 44 | -(void)whenKeyboardShow:(NSNotification*) notif{ 45 | //获取当前键盘高度 46 | NSDictionary* info = notif.userInfo; 47 | NSValue* value = [info objectForKey:UIKeyboardFrameEndUserInfoKey]; 48 | CGRect keyboardRect = [value CGRectValue]; 49 | 50 | //重设scrollview高度 51 | [UIView animateWithDuration:0.1f animations:^{ 52 | [self.scrollView setContentOffset:CGPointMake(0, keyboardRect.size.height)]; 53 | [self.textField setFrame:CGRectMake(0,568-keyboardRect.size.height-30,320,30)]; 54 | }]; 55 | //若没有scrollview可以使用uiview位移 56 | //CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0.0, -keyboardRect.size.height/2); 57 | //[_txt_email setTransform:myTransform]; 58 | //[_txt_pwd setTransform:myTransform]; 59 | 60 | } 61 | ```` 62 | -------------------------------------------------------------------------------- /1_UIKit/样式/UILabel_Attributes.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 1.NSKernAttributeName: 4 | 10 调整字句 kerning 字句调整 5 | 6 | ## 2.NSFontAttributeName : 7 | [UIFont systemFontOfSize:_fontSize] 设置字体 8 | 9 | 10 | ## 3.NSForegroundColorAttributeName 11 | :[UIColor redColor] 设置文字颜色 12 | 13 | 14 | ## 4.NSParagraphStyleAttributeName : 15 | paragraph 设置段落样式 16 | NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; 17 | paragraph.alignment = NSTextAlignmentCenter; 18 | 19 | 20 | ## 6.NSBackgroundColorAttributeName: 21 | [UIColor blackColor] 设置背景颜色 22 | 23 | 24 | ## 7.NSStrokeColorAttributeName 25 | 设置文字描边颜色,需要和NSStrokeWidthAttributeName设置描边宽度,这样就能使文字空心. 26 | NSStrokeWidthAttributeName这个属性所对应的值是一个 NSNumber 对象(小数)。该值改变描边宽度(相对于字体size 的百分比)。默认为 0,即不改变。正数只改变描边宽度。负数同时改变文字的描边和填充宽度。例如,对于常见的空心字,这个值通常为3.0。 27 | 28 | 同时设置了空心的两个属性,并且NSStrokeWidthAttributeName属性设置为整数,文字前景色就无效果了 29 | 30 | ## 8. NSStrikethroughStyleAttributeName 添加删除线,strikethrough删除线 31 | 32 | ## 9. NSUnderlineStyleAttributeName 添加下划线 33 | 34 | ## 10. NSShadowAttributeName 设置阴影,单独设置不好使,必须和其他属性搭配才好使 35 | 36 | ## 11.NSVerticalGlyphFormAttributeName 37 | 该属性所对应的值是一个 NSNumber 对象(整数)。0 表示横排文本。1 表示竖排文本。在 iOS 中,总是使用横排文本,0 以外的值都未定义。 38 | 39 | ## 12. NSObliquenessAttributeName设置字体倾斜。 40 | 41 | ## 13. NSExpansionAttributeName 设置文本扁平化 42 | 43 | 参考:http://www.cnblogs.com/qingche/p/3574995.html 44 | -------------------------------------------------------------------------------- /1_UIKit/样式/UILabel使用例子.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## label样式设置例子 4 | 5 | ````objc 6 | //设置lable样式 7 | //设置位置和大小 8 | self.myLable2 = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 640, 400)]; 9 | NSString *string = @"sadsadsadsadsadsadsdasadsadsadsadsadsadsdasadsadsadsadsadsadsdasadsadsadsaadsadsdasadsadsadsadsadsadsdasadsadsadsadsadsadsdasadsadsadsadsadsadsdasadsadsadsadsadsadsdasadsadsadsadsadsadsdasadsadsadsadsadsadsdasadsadsadsaadsadsdasadsadsadsadsadsadsdasadsadsadsadsadsadsdasadsadsadsadsadsadsda"; 10 | //设置多行显示 11 | self.myLable2.lineBreakMode = NSLineBreakByWordWrapping; 12 | self.myLable2.numberOfLines = 0; 13 | //设置行间距 14 | NSMutableAttributedString *attrbutedString = [[NSMutableAttributedString alloc]initWithString:string]; 15 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init]; 16 | [paragraphStyle setLineSpacing:LINESPACE]; 17 | [attrbutedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [string length])]; 18 | self.myLable2.attributedText = attrbutedString; 19 | 20 | //动态计算uilabel的宽高,这里以高度为例 21 | UILabel *textcontent = [[UILabel alloc]init]; 22 | textcontent.text = @"新的一年,希望家人和朋友都身体健康,工作顺利,心想事成新的一年,希望家人和朋友都身体健康,工作顺利,心想事成~~新的一年,希望家人和朋友都身体健康,工作顺利,心想事成新的一年,希望家人和朋友都身体健康,工作顺利,心想事成~~"; 23 | textcontent.textColor = [UIColor blackColor]; 24 | textcontent.font = [UIFont systemFontOfSize:12]; 25 | textcontent.lineBreakMode = NSLineBreakByWordWrapping; 26 | textcontent.numberOfLines = 0; 27 | CGSize size = CGSizeMake(260, CGFLOAT_MAX);//宽度,最大高度值 28 | CGSize contentsize = [textcontent.text sizeWithFont:textcontent.font constrainedToSize:size lineBreakMode:textcontent.lineBreakMode]; 29 | textcontent.frame = CGRectMake(60, 40, contentsize.width, contentsize.height); 30 | [textcontent setBackgroundColor:[UIColor grayColor]]; 31 | [self.contentView addSubview:textcontent]; 32 | 33 | ```` 34 | -------------------------------------------------------------------------------- /1_UIKit/样式/uiview超出部分不显示.md: -------------------------------------------------------------------------------- 1 | ## uiview超出部分不显示的三种方式 2 | 3 | ````objc 4 | 5 | 1: [self.view setClipsToBounds:YES]; 6 | 7 | 2: [self.view.layer setMasksToBounds:YES]; 8 | 9 | 3: 在故事板或者是xib界面,选择UIView 在 attributes 那一栏选择 Clip to subview 10 | 11 | ```` 12 | -------------------------------------------------------------------------------- /1_UIKit/样式/图片的拉伸.md: -------------------------------------------------------------------------------- 1 | ## 图片拉伸共有三种方法: 2 | 3 | ````objc 4 | 5 | - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight 6 | 示例: 7 | // 左端盖宽度 8 | NSInteger leftCapWidth = image.size.width * 0.5f; 9 | // 顶端盖高度 10 | NSInteger topCapHeight = image.size.height * 0.5f; 11 | // 重新赋值 12 | image = [image stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight]; 13 | 14 | 15 | - (UIImage *)resizableImageCapInsets:(UIEdgeInsets)Insets 16 | 17 | // 重新赋值 18 | CGFloat top = 30; // 顶端盖高度 19 | CGFloat bottom = 30 ; // 底端盖高度 20 | CGFloat left = 35; // 左端盖宽度 21 | CGFloat right = 35; // 右端盖宽度 22 | UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right); 23 | // 伸缩后重新赋值 24 | image = [image resizableImageWithCapInsets:insets]; 25 | 26 | - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode 27 | 28 | // 重新赋值 29 | CGFloat top = 30; // 顶端盖高度 30 | CGFloat bottom = 30 ; // 底端盖高度 31 | CGFloat left = 35; // 左端盖宽度 32 | CGFloat right = 35; // 右端盖宽度 33 | UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right); 34 | // 伸缩后重新赋值 UIImageResizingModeTile:平铺 UIImageResizingModeStretch:拉伸 35 | image = [image resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeTile]; 36 | 37 | ```` 38 | 39 | ## siwft 实现 40 | 41 | ```siwft 42 | 43 | var image = UIImage(named:"bg.png") 44 | // 左端盖宽度 45 | var leftCapWidth:Int = Int(image!.size.width * 0.5) 46 | // 顶端盖高度 47 | var topCapHeight:Int = Int(image!.size.height * 0.5) 48 | 49 | image = image!.stretchableImageWithLeftCapWidth(leftCapWidth,topCapHeight: topCapHeight) 50 | 51 | ```` 52 | 53 | -------------------------------------------------------------------------------- /1_UIKit/样式/圆角imageview.md: -------------------------------------------------------------------------------- 1 | ````objc 2 | //设置圆角边框 3 | self.image.layer.cornerRadius = 37.1f; 4 | self.image.layer.masksToBounds = YES; 5 | //设置边框及边框颜色 6 | self.image.layer.borderWidth = 1; 7 | self.image.layer.borderColor =[ [UIColor whiteColor] CGColor]; 8 | ```` 9 | -------------------------------------------------------------------------------- /2_ThirdParty/CocoaLumberjack的使用.md: -------------------------------------------------------------------------------- 1 | 2 | ## CocoaLumberjack的使用 3 | 4 | 5 | 1:准备 6 | 7 | ````objc 8 | platform :ios, '5.0' 9 | pod 'CocoaLumberjack' 10 | ```` 11 | 12 | 2:项目配置 13 | 14 | ````objc 15 | #import 16 | 17 | ----一共有5种不同等级-------- 18 | Error 19 | Warn 20 | Info 21 | Debug 22 | Verbose 23 | 24 | applicationDidFinishLaunching中添加 25 | [DDLog addLogger:[DDASLLogger sharedInstance]]; 26 | [DDLog addLogger:[DDTTYLogger sharedInstance]]; 27 | //全局配置显示的告警级别() 28 | # [DDLog addLogger:[DDASLLogger sharedInstance] withLevel:DDLogLevelError]; 29 | # [DDLog addLogger:[DDTTYLogger sharedInstance] withLevel:DDLogLevelWarning]; 30 | 31 | ``` 32 | 33 | 34 | 35 | 3:配置log显示的颜色 36 | 37 | ````objc 38 | 39 | - 彩色日志显示需要插件XcodeColors插件支持,我安装的是:https://github.com/rvi/XcodeColors 40 | - Demo里测试日志颜色正常,在自己的项目里就不会显示颜色 41 | 在xcode导航选择 project -》 scheme -》 run -》 Arguments 42 | add new Environment Variable named "XcodeColors", with a value of "YES" 43 | 44 | - 默认的颜色是error是红色字体,waring是黄色字体,其他都是黑色字体,你也可以自定义颜色。 45 | 46 | [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor colorWithRed:1.000 green:0.000 blue:0.502 alpha:1.000] forFlag:DDLogFlagError]; 47 | [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor colorWithRed:1.000 green:0.502 blue:0.000 alpha:1.000] forFlag:DDLogFlagWarning]; 48 | [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor colorWithRed:0.000 green:0.251 blue:0.502 alpha:1.000] forFlag:DDLogFlagInfo]; 49 | [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor blackColor] forFlag:DDLogFlagDebug]; 50 | //[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor redColor] backgroundColor:[UIColor greenColor] forFlag:DDLogFlagVerbose]; 51 | 52 | ```` 53 | 54 | 55 | 56 | 4:示例: 57 | 58 | ````objc 59 | 60 | PrefixHeader_pch 61 | #import 62 | 63 | AppDelegate.h 64 | @interface AppDelegate () 65 | 66 | @end 67 | 68 | @implementation AppDelegate 69 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 70 | // Override point for customization after application launch. 71 | 72 | [self DDLogConfiguration]; 73 | return YES; 74 | } 75 | //DDLog配置 76 | -(void) DDLogConfiguration{ 77 | 78 | [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor colorWithRed:1.000 green:0.000 blue:0.502 alpha:1.000] forFlag:DDLogFlagError]; 79 | [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor colorWithRed:1.000 green:0.502 blue:0.000 alpha:1.000] forFlag:DDLogFlagWarning]; 80 | [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor colorWithRed:0.000 green:0.251 blue:0.502 alpha:1.000] forFlag:DDLogFlagInfo]; 81 | [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor blackColor] forFlag:DDLogFlagDebug]; 82 | // [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor redColor] backgroundColor:[UIColor greenColor] forFlag:DDLogFlagVerbose]; 83 | 84 | //允许颜色 85 | [[DDTTYLogger sharedInstance] setColorsEnabled:YES]; 86 | [DDLog addLogger:[DDASLLogger sharedInstance]]; 87 | [DDLog addLogger:[DDTTYLogger sharedInstance]]; 88 | //[DDLog addLogger:[DDASLLogger sharedInstance] withLevel:DDLogLevelError]; 89 | //[DDLog addLogger:[DDTTYLogger sharedInstance] withLevel:DDLogLevelWarning]; 90 | 91 | } 92 | 93 | ViewController.h============== 94 | @implementation ViewController 95 | 96 | - (void)viewDidLoad { 97 | [super viewDidLoad]; 98 | 99 | DDLogError(@"DDLogError"); 100 | DDLogWarn(@"DDLogWarn"); 101 | DDLogInfo(@"DDLogInfo"); 102 | DDLogDebug(@"DDLogDebug"); 103 | DDLogVerbose(@"DDLogVerbose"); 104 | 105 | } 106 | 107 | - (void)didReceiveMemoryWarning { 108 | [super didReceiveMemoryWarning]; 109 | // Dispose of any resources that can be recreated. 110 | } 111 | 112 | @end 113 | 114 | ```` 115 | -------------------------------------------------------------------------------- /2_ThirdParty/MJRefreash的使用.md: -------------------------------------------------------------------------------- 1 | ## MJRefreash的使用 2 | 3 | 4 | ## 1:安装: 5 | 6 | ```` 7 | cocoapods导入:pod 'MJRefresh' 8 | 手动导入: 9 | 将MJRefresh文件夹中的所有文件拽入项目中 10 | 导入主头文件:#import "MJRefresh.h" 11 | ```` 12 | 13 | ## 2:基本使用 14 | 15 | ````objc 16 | 17 | - (void)configMJRefresh{ 18 | 19 | //配置上拉刷新和加载控件 20 | [self.table addHeaderWithTarget:self action:@selector(headerRereshing)]; 21 | [self.table addFooterWithTarget:self action:@selector(footerRereshing)]; 22 | //设置加载的文字 23 | self.table.headerRefreshingText = @"玩命加载中"; 24 | self.table.headerPullToRefreshText = @"下拉开始刷新"; 25 | self.table.headerReleaseToRefreshText = @"松开开始刷新"; 26 | self.table.footerRefreshingText = @"玩命加载中"; 27 | self.table.footerPullToRefreshText = @"下拉开始刷新"; 28 | self.table.footerReleaseToRefreshText = @"松开开始刷新"; 29 | } 30 | //刷新和加载方法 31 | - (void)headerRereshing{ 32 | NSLog(@"headerRereshing"); 33 | [self.table headerEndRefreshing]; 34 | //[self.table headerBeginRefreshing]; 35 | } 36 | - (void)footerRereshing{ 37 | NSLog(@"footerRereshing"); 38 | [self.table footerEndRefreshing]; 39 | //[self.table footerBeginRefreshing]; 40 | } 41 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 42 | 43 | NSString *cellIdentifier = @"cell"; 44 | ListCellView *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 45 | if (cell == nil) 46 | { 47 | cell = (ListCellView *)[[[NSBundle mainBundle]loadNibNamed:@"ListCellView" owner:self options:nil] firstObject]; 48 | } 49 | //配置cell 50 | NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:[self.data objectAtIndex:[indexPath row]],@"title", nil]; 51 | [cell configStyle:dic]; 52 | return cell; 53 | } 54 | @end 55 | 56 | ```` 57 | -------------------------------------------------------------------------------- /2_ThirdParty/RestKit使用.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ````objc 4 | 5 | #import "ViewController.h" 6 | #import "PAResponse.h" 7 | 8 | @interface ViewController () 9 | 10 | @end 11 | 12 | @implementation ViewController 13 | 14 | - (void)viewDidLoad { 15 | [super viewDidLoad]; 16 | 17 | RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[PAResponse class]]; 18 | NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx 19 | 20 | [responseMapping addAttributeMappingsFromDictionary:@{ 21 | @"status": @"status", 22 | @"msg": @"msg", 23 | }]; 24 | RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:[PAUser class]]; 25 | [userMapping addAttributeMappingsFromDictionary:@{ 26 | @"userId": @"userId", 27 | @"username": @"username", 28 | @"email": @"email", 29 | @"password": @"password", 30 | @"headportait": @"headportait", 31 | @"token": @"token" 32 | }]; 33 | 34 | [responseMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"data" 35 | toKeyPath:@"data" 36 | withMapping:userMapping] 37 | ]; 38 | 39 | RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping method:RKRequestMethodAny pathPattern:nil keyPath:nil statusCodes:statusCodes]; 40 | // RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping method:RKRequestMethodAny pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 41 | 42 | 43 | 44 | NSLog(@"%s==========================================",__func__); 45 | 46 | // RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://plantAssistantapi.jumppo.com"]]; 47 | RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://localhost:8070"]]; 48 | NSDictionary *requestParameter = @{@"name":@"liuyanwei",@"pwd":@"weiwei"}; 49 | 50 | // [manager setAcceptHeaderWithMIMEType:RKMIMETypeFormURLEncoded]; 51 | [manager setRequestSerializationMIMEType:RKMIMETypeFormURLEncoded]; 52 | [manager addResponseDescriptor:responseDescriptor]; 53 | // [manager requestWithObject:nil method:RKRequestMethodPOST path:@"/user/login" parameters:requestParameter]; 54 | [manager postObject:nil path:@"/user/login" parameters:requestParameter success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { 55 | // 56 | PAResponse *result = [mappingResult firstObject]; 57 | NSLog(@"%@",result); 58 | if([result.data isKindOfClass:[PAUser class]]){ 59 | PAUser *user = (PAUser *)result.data; 60 | NSLog(@"%@",user); 61 | } 62 | 63 | } failure:^(RKObjectRequestOperation *operation, NSError *error) { 64 | // 65 | NSLog(@"%@",error); 66 | }]; 67 | 68 | } 69 | 70 | 71 | - (void)didReceiveMemoryWarning { 72 | [super didReceiveMemoryWarning]; 73 | // Dispose of any resources that can be recreated. 74 | } 75 | 76 | @end 77 | 78 | 79 | #import 80 | #import "PAUser.h" 81 | 82 | 83 | 84 | @interface PAResponse : NSObject 85 | 86 | @property (nonatomic, copy) NSString *status; 87 | @property (nonatomic, copy) NSString *msg; 88 | @property (nonatomic) NSObject *data; 89 | 90 | @end 91 | 92 | 93 | #import 94 | 95 | @interface PAUser : NSObject 96 | 97 | @property (nonatomic ,copy) NSString *userId; 98 | @property (nonatomic ,copy) NSString *username; 99 | @property (nonatomic ,copy) NSString *email; 100 | @property (nonatomic ,copy) NSString *password; 101 | @property (nonatomic ,copy) NSString *headportait; 102 | @property (nonatomic ,copy) NSString *token; 103 | 104 | @end 105 | 106 | ```` 107 | -------------------------------------------------------------------------------- /2_ThirdParty/SDWebImage使用.md: -------------------------------------------------------------------------------- 1 | # SDWebImage使用 2 | 3 | 4 | ## SDWebImage引用 5 | 6 | SDWebImage 3.6 手动引用 7 | 8 | ```` 9 | 1:下载SDWebImage.framework 10 | 2:右键项目-add fileto ,选择SDWebImage.framework 11 | 3:添加依赖库 1:ImageIO 2:MapKit 12 | 4:build setting => other linker flags: 添加参数-ObjC 13 | ```` 14 | 15 | 注意!!!!!!!!!!!!!!!!!!!!!!!!!!!! 16 | 17 | - 1:添加成功后项目中sdwebimage是以包出现的,并且bulid phases 中link binary中会增加sdwebimage 18 | - 2: 若不形行,先清理项目,删除生成的项目文件,再从新编译添加 19 | 20 | 21 | 使用cocoapod添加 22 | 23 | ````objc 24 | 25 | 26 | ==========================SDWebImage使用============================================== 27 | SDWebImage使用 28 | SDWebImage这个类库提供一个UIImageView类别以支持加载来自网络的远程图片。具有缓存管理、异步下载、同一个URL下载次数控制和优化等特征。 29 | 30 | 将SDWebImage类库添加入工程时,一定注意需要添加MapKit.framework,如图所示,因为MKAnnotationView+WebCache.h依赖该framework。 31 | 32 | 1. UITableView使用UIImageView+WebCache类(基本应用,UIImageView的一个category) 33 | 34 | 前提#import导入文件,然后在tableview的cellForRowAtIndexPath:方法下: 35 | 36 | 37 | 1 38 | 2 #import 39 | 3 40 | 4 41 | 5 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 42 | 6 { 43 | 7 static NSString *MyIdentifier = @"MyIdentifier"; 44 | 8 45 | 9 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 46 | 10 47 | 11 if (cell == nil) 48 | 12 { 49 | 13 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 50 | 14 reuseIdentifier:MyIdentifier] autorelease]; 51 | 15 } 52 | 16 53 | 17 // Here we use the new provided setImageWithURL: method to load the web image 54 | 18 [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] 55 | 19 placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; 56 | 20 57 | 21 cell.textLabel.text = @"My Text"; 58 | 22 return cell; 59 | 23 } 60 | 复制代码 61 | 1 [imageView setImageWithURL:[NSURL URLWithString:@http://www.domain.com/path/image.jpg]]; 62 | 针对iOS4+目标平台,还可以使用如下块语句: 63 | 64 | 1 // Here we use the new provided setImageWithURL: method to load the web image 65 | 2 [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] 66 | 3 placeholderImage:[UIImage imageNamed:@"placeholder.png"] 67 | 4 success:^(UIImage *image) {... success code here ...} 68 | 5 failure:^(NSError *error) {... failure code here ...}]; 69 | 2. 使用SDWebImageManager类:可以进行一些异步加载的工作。 70 | 71 | 复制代码 72 | 1 SDWebImageManager *manager = [SDWebImageManager sharedManager]; 73 | 2 UIImage *cachedImage = [manager imageWithURL:url]; // 将需要缓存的图片加载进来 74 | 3 if (cachedImage) { 75 | 4 // 如果Cache命中,则直接利用缓存的图片进行有关操作 76 | 5 // Use the cached image immediatly 77 | 6 } else { 78 | 7 // 如果Cache没有命中,则去下载指定网络位置的图片,并且给出一个委托方法 79 | 8 // Start an async download 80 | 9 [manager downloadWithURL:url delegate:self]; 81 | 10 } 82 | 复制代码 83 | 当然你的类要实现SDWebImageManagerDelegate协议,并且要实现协议的webImageManager:didFinishWithImage:方法。 84 | 85 | 1 // 当下载完成后,调用回调方法,使下载的图片显示 86 | 2 - (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image { 87 | 3 // Do something with the downloaded image 88 | 4 } 89 | 3. 独立的异步图像下载 90 | 可能会单独用到异步图片下载,则一定要用downloaderWithURL:delegate:来建立一个SDWebImageDownloader实例。 91 | 92 | 1 downloader =[SDWebImageDownloader downloaderWithURL:url delegate:self]; 93 | 这样SDWebImageDownloaderDelegate协议的方法imageDownloader:didFinishWithImage:被调用时下载会立即开始并完成。 94 | 95 | 4. 独立的异步图像缓存 96 | 97 | SDImageCache类提供一个创建空缓存的实例,并用方法imageForKey:来寻找当前缓存。 98 | 99 | 1 UIImage*myCachedImage = [[SDImageCache sharedImageCache] imageFromKey:myCacheKey]; 100 | 存储一个图像到缓存是使用方法storeImage: forKey: 101 | 102 | 1 [[SDImageCachesharedImageCache] storeImage:myImage forKey:myCacheKey]; 103 | 默认情况下,图像将被存储在内存缓存和磁盘缓存中。如果仅仅是想内存缓存中,要使用storeImage:forKey:toDisk:方法的第三个参数带一负值 104 | 来替代。 105 | 106 | ======================================================== 107 | 引用地址 108 | http://www.cnblogs.com/wangshengl9263/p/3347933.html 109 | 110 | ```` 111 | 112 | -------------------------------------------------------------------------------- /2_ThirdParty/SVProgressHUD的使用.md: -------------------------------------------------------------------------------- 1 | SVProgressHUD的使用 2 | 3 | ```` 4 | 安装: pod 'SVProgressHUD' 5 | 引入头: #import "SVProgressHUD.h" 6 | 7 | ```` 8 | 9 | 测试方法 10 | 11 | ````objc 12 | 13 | [SVProgressHUD show]; 14 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 15 | // time-consuming task 16 | sleep(3); 17 | dispatch_async(dispatch_get_main_queue(), ^{ 18 | [SVProgressHUD dismiss]; 19 | }); 20 | }); 21 | 22 | ```` 23 | 24 | 示例: 25 | 26 | ````obcj 27 | 28 | #import "ViewController.h" 29 | #import "SVProgressHUD.h" 30 | 31 | @implementation ViewController 32 | 33 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { 34 | return YES; 35 | } 36 | 37 | 38 | #pragma mark - Notification Methods Sample 39 | 40 | - (void)viewWillAppear:(BOOL)animated { 41 | [super viewWillAppear:animated]; 42 | 43 | [[NSNotificationCenter defaultCenter] addObserver:self 44 | selector:@selector(handleNotification:) 45 | name:SVProgressHUDWillAppearNotification 46 | object:nil]; 47 | 48 | [[NSNotificationCenter defaultCenter] addObserver:self 49 | selector:@selector(handleNotification:) 50 | name:SVProgressHUDDidAppearNotification 51 | object:nil]; 52 | 53 | [[NSNotificationCenter defaultCenter] addObserver:self 54 | selector:@selector(handleNotification:) 55 | name:SVProgressHUDWillDisappearNotification 56 | object:nil]; 57 | 58 | [[NSNotificationCenter defaultCenter] addObserver:self 59 | selector:@selector(handleNotification:) 60 | name:SVProgressHUDDidDisappearNotification 61 | object:nil]; 62 | } 63 | 64 | - (void)handleNotification:(NSNotification *)notif 65 | { 66 | NSLog(@"Notification recieved: %@", notif.name); 67 | NSLog(@"Status user info key: %@", [notif.userInfo objectForKey:SVProgressHUDStatusUserInfoKey]); 68 | } 69 | 70 | 71 | #pragma mark - Show Methods Sample 72 | 73 | - (void)show { 74 | [SVProgressHUD show]; 75 | } 76 | 77 | - (void)showWithStatus { 78 | [SVProgressHUD showWithStatus:@"Doing Stuff"]; 79 | } 80 | 81 | static float progress = 0.0f; 82 | 83 | - (IBAction)showWithProgress:(id)sender { 84 | progress = 0.0f; 85 | [SVProgressHUD showProgress:0 status:@"Loading"]; 86 | [self performSelector:@selector(increaseProgress) withObject:nil afterDelay:0.3f]; 87 | } 88 | 89 | - (void)increaseProgress { 90 | progress+=0.1f; 91 | [SVProgressHUD showProgress:progress status:@"Loading"]; 92 | 93 | if(progress < 1.0f) 94 | [self performSelector:@selector(increaseProgress) withObject:nil afterDelay:0.3f]; 95 | else 96 | [self performSelector:@selector(dismiss) withObject:nil afterDelay:0.4f]; 97 | } 98 | 99 | 100 | #pragma mark - Dismiss Methods Sample 101 | 102 | - (void)dismiss { 103 | [SVProgressHUD dismiss]; 104 | } 105 | 106 | - (IBAction)dismissInfo{ 107 | [SVProgressHUD showInfoWithStatus:@"Useful Information."]; 108 | } 109 | 110 | - (void)dismissSuccess { 111 | [SVProgressHUD showSuccessWithStatus:@"Great Success!"]; 112 | } 113 | 114 | - (void)dismissError { 115 | [SVProgressHUD showErrorWithStatus:@"Failed with Error"]; 116 | } 117 | 118 | @end 119 | 120 | 121 | ```` 122 | -------------------------------------------------------------------------------- /2_ThirdParty/SVPullToRefresh使用.md: -------------------------------------------------------------------------------- 1 | ## SVPullToRefr的使用 2 | 3 | 4 | ## 注册下拉刷新功能 5 | 6 | ````objc 7 | __weak BaseTableViewController *weakSelf = self; 8 | [self.tableView addPullToRefreshWithActionHandler:^{ 9 | [weakSelf insertRowAtTop]; 10 | }]; 11 | //注册上拉刷新功能 12 | [self.tableView addInfiniteScrollingWithActionHandler:^{ 13 | [weakSelf insertRowAtBottom]; 14 | }]; 15 | ```` 16 | 17 | 18 | ## 业务步骤 19 | 20 | ````objc 21 | 22 | //开始更新 23 | [self.tableView beginUpdates]; 24 | 25 | [NSThread sleepForTimeInterval:1]; 26 | 27 | //结束更新 28 | [self.tableView endUpdates]; 29 | 30 | //停止菊花 31 | [self.tableView.pullToRefreshView stopAnimating]; 32 | 33 | ```` 34 | 35 | ## 程序自动调用下拉刷新 36 | 37 | ````objc 38 | 39 | [csharp] view plaincopy 40 | [tableView triggerPullToRefresh]; 41 | ```` 42 | 43 | ## 临时性禁用下拉刷新 44 | 45 | ```objc 46 | 47 | [csharp] view plaincopy 48 | tableView.showsPullToRefresh = NO; 49 | SVPullToRefresh的UI支持自定义 50 | 下拉刷新对应的view名叫pullToRefreshView,有如下属性和方法修改它的显示。 51 | 52 | [csharp] view plaincopy 53 | @property (nonatomic, strong) UIColor *arrowColor; 54 | @property (nonatomic, strong) UIColor *textColor; 55 | @property (nonatomic, readwrite) UIActivityIndicatorViewStyle activityIndicatorViewStyle; 56 | 57 | - (void)setTitle:(NSString *)title forState:(SVPullToRefreshState)state; 58 | - (void)setSubtitle:(NSString *)subtitle forState:(SVPullToRefreshState)state; 59 | - (void)setCustomView:(UIView *)view forState:(SVPullToRefreshState)state; 60 | 61 | //简单用法,比如下面一行代码就修改了下拉箭头的颜色。 62 | [csharp] view plaincopy 63 | tableView.pullToRefreshView.arrowColor = [UIColor whiteColor]; 64 | ```` 65 | 66 | 67 | ## 引用 68 | 69 | http://blog.csdn.net/itenric/article/details/12391185 70 | 71 | http://www.jianshu.com/p/783ac913120d 72 | -------------------------------------------------------------------------------- /2_ThirdParty/facebook:pop的使用.md: -------------------------------------------------------------------------------- 1 | 2 | # facebook/pop的使用 3 | 4 | ## 1:安装 5 | 6 | ```` 7 | pod 'pop', '~> 1.0' 8 | #import 9 | ```` 10 | 11 | ## 步骤 2:创建动效 12 | 13 | 使用POP可以创建4类动效:: spring, decay, basic and custom. 14 | 15 | ````objc 16 | Spring (弹性)动效可以赋予物体愉悦的弹性效果 17 | POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBounds]; 18 | 19 | Decay (衰减) 动效可以用来逐渐减慢物体的速度至停止 20 | POPDecayAnimation *anim = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPositionX]; 21 | 22 | Basic(基本)动效可以在给定时间的运动中插入数值调整运动节奏 23 | POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPViewAlpha]; 24 | 25 | Custom(自定义)动效可以让设计值创建自定义动效,只需简单处理CADisplayLink,并联系时间-运动关系 26 | 在这片简短教程中将不涵盖自定义动效,大家可以看看POP的Github来获取更多进阶知识https://github.com/facebook/pop 27 | 28 | ```` 29 | 30 | ## 步骤3: 给动效添加属性 31 | 32 | ```` 33 | Pop 让我们可以这样设置动效的属性: 34 | 35 | velocity : anim.velocity = @(1000.); 36 | 37 | fromValue: anim.fromValue = @(0.0); 38 | 39 | toValue: anim.toValue = @(1.0); 40 | 41 | bounciness: anim.springBounciness = 10; 42 | 43 | ```` 44 | 45 | ## 步骤4 :动起来 46 | 47 | 若想让物体动起来,只需要添加步骤3所创建的东西到视图。 48 | 49 | ````objc 50 | [self.yourView.layer pop_addAnimation:anim forKey:@"typeANameForYourAnimationHere"]; 51 | 这就是POP简单创建动效的教程。大家可以看看例子来理解如何创建动效。争取努力变得技艺纯熟吧。 52 | ```` 53 | 54 | 55 | ## 动效案例 56 | 57 | ````objc 58 | 59 | ///这个动效将按钮缩小到一半 60 | -(void)scale { 61 | POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY]; 62 | scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(0.7, 0.7)]; 63 | scaleAnimation.springBounciness = 10.f; 64 | [self.Button.layer pop_addAnimation:scaleAnimation forKey:@"scaleAnim"]; 65 | } 66 | 67 | 68 | ///这个动效将按钮旋转 69 | -(void)rotaion { 70 | POPSpringAnimation *rotationAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerRotation]; 71 | rotationAnimation.beginTime = CACurrentMediaTime() + 0.2; 72 | rotationAnimation.toValue = @(1.2); 73 | rotationAnimation.springBounciness = 10.f; 74 | rotationAnimation.springSpeed = 3; 75 | [self.Button.layer pop_addAnimation:rotationAnimation forKey:@"rotationAnim"]; 76 | } 77 | 78 | //这个改变透明度: 79 | -(void)Alpha { 80 | POPBasicAnimation *opacityAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerOpacity]; 81 | opacityAnimation.toValue = @(0.5); 82 | [self.Button.layer pop_addAnimation:opacityAnimation forKey:@"opacityAnimation"]; 83 | } 84 | 85 | 86 | ```` 87 | Pop Github : https://github.com/facebook/pop 88 | 89 | Popping -Pop案例 : https://github.com/schneiderandre/popping 90 | 91 | POP使用教程: https://github.com/maxmyers/FacebookPop 92 | 93 | -------------------------------------------------------------------------------- /2_ThirdParty/json-framework的使用.md: -------------------------------------------------------------------------------- 1 | ## json-framework的使用 2 | 3 | ## 配置 以4.01为准 4 | 5 | ````objc 6 | 7 | 1:手动:下载源码后将文件夹中src-main-objc中代码考到项目中 8 | 2:自动:pod 'SBJson', '~> 4.0.1' 9 | 10 | ```` 11 | 12 | ## 使用 13 | 14 | ````objc 15 | 16 | //1:设置代码执行block和初始化工具 17 | 18 | //初始化读取类 19 | SBJson4Writer *writer = [[SBJson4Writer alloc] init]; 20 | //初始化block 21 | SBJson4ValueBlock block = ^(id obj, BOOL *stop) { 22 | //处理json数据和类型的地方 23 | 24 | }; 25 | //初始化解析类 26 | SBJson4Parser *parser = [SBJson4Parser parserWithBlock:block allowMultiRoot:NO unwrapRootArray:NO errorHandler:nil]; 27 | //执行解析 28 | [parser parse:[jsonString dataUsingEncoding:NSUTF8StringEncoding]]; 29 | 30 | ```` 31 | 32 | ## 解析例子 33 | 34 | ````objc 35 | 36 | ---------解析为string 37 | SBJson4Writer *writer = [[SBJson4Writer alloc] init]; 38 | //方式1:通过nsdata转string 39 | id data = [writer dataWithObject:obj]; 40 | NSString *str = [[NSString alloc]initWithData:data encoding:(NSUTF8StringEncoding)]; 41 | //方式2,直接使用[writer stringWithObject:obj] 42 | NSLog(@"Found: %@", [writer stringWithObject:obj]); 43 | 44 | ---------解析为dict 45 | SBJson4Writer *writer = [[SBJson4Writer alloc] init]; 46 | //解析为字典 47 | id data = [writer dataWithObject:obj]; 48 | NSDictionary *dic = [NSJSONSerialization 49 | JSONObjectWithData:data 50 | options:kNilOptions 51 | error:nil]; 52 | 53 | //解析字典下的内容 54 | NSDictionary *china = [dic objectForKey:@"中国"]; 55 | NSLog(@"key=北京%@",[china objectForKey:@"北京"]); 56 | 57 | ---------解析为array 58 | 59 | ---------解析为对象 60 | 61 | NSString *jsonString=@"{\"中国\":{ \"北京\":{\"北京1\":1,\"北京2\":2,\"北京3\":3}, \"上海\":{\"上海1\":4,\"上海2\":5,\"上海3\":6},\"广州\":{\"广州1\":7,\"广州2\":8,\"广州3\":9}}}"; 62 | 63 | SBJson4ValueBlock block = ^(id obj, BOOL *stop) { 64 | SBJson4Writer *writer = [[SBJson4Writer alloc] init]; 65 | id data = [writer dataWithObject:obj]; 66 | NSLog(@"Found: %@", [writer stringWithObject:obj]); 67 | 68 | // NSMutableDictionary *dic = [NSMutableDictionary 69 | NSString *str = [[NSString alloc]initWithData:data encoding:(NSUTF8StringEncoding)]; 70 | //NSLog(@"Found: %@",str); 71 | 72 | }; 73 | 74 | ```` 75 | 76 | -------------------------------------------------------------------------------- /2_ThirdParty/第三方常用库.md: -------------------------------------------------------------------------------- 1 | # 第三方常用库: 2 | 3 | 4 | github IOS库排行 [objc](https://github.com/search?l=Objective-C&o=desc&q=stars%3A%3E1&s=stars&type=Repositories) [swift](https://github.com/search?l=swift&o=desc&q=stars%3A%3E1&s=stars&type=Repositories) 5 | 6 | ## 必备、很常用、推荐 7 | 8 | [SDWebImage 图片异步加载及缓存](https://github.com/rs/SDWebImage) 9 | 10 | [AFNetworking 网络请求](https://github.com/AFNetworking/AFNetworking) 11 | 12 | [SVProgressHUD 提示效果](https://github.com/samvermette/SVProgressHUD) 13 | 14 | [CocoaLumberjack 日志框](https://github.com/CocoaLumberjack/CocoaLumberjack) 15 | 16 | Masonry :ui自适应框架 Objective-C 17 | 18 | SnapKit/SnapKit: ui自适应框架 swift 19 | 20 | DZNEmptyDataSet:tableview,空数据样式 21 | 22 | https://github.com/dzenbot/DZNEmptyDataSet 23 | 24 | 25 | ## cocoapod方式 26 | 27 | ```` 28 | platform :ios, '8.0' 29 | pod 'SDWebImage', '~>3.6' 30 | pod 'AFNetworking', '~> 2.0' 31 | pod 'MJRefresh' 32 | pod 'SVProgressHUD' 33 | pod 'CocoaLumberjack','~> 2.0' 34 | pod 'Masonry' 35 | pod 'DZNEmptyDataSet' 36 | ```` 37 | 38 | ```` 39 | 40 | =========工具类============= 41 | Chameleon for iOS 42 | 颜色主题库,提供flatColor许多颜色相关的便捷的方法。 43 | GitHub:https://github.com/ViccAlexander/Chameleon 44 | pod: 45 | -Objective-C :pod'ChameleonFramework' 46 | -swift :pod'ChameleonFramework/Swift' 47 | 48 | 49 | ============图表控件================ 50 | ANDLineChartView 282+s 51 | 折线图 52 | https://github.com/anaglik/ANDLineChartView 53 | pod "ANDLineChartView" 54 | 55 | SHLineGraphView 200+s 56 | https://github.com/grevolution/SHLineGraphView 57 | 58 | JBChartView 2000+s 59 | 有图有表 60 | https://github.com/Jawbone/JBChartView 61 | 62 | BEMSimpleLineGraph 1500s+ 63 | 实时、折线图 64 | https://github.com/Boris-Em/BEMSimpleLineGraph 65 | pod 'BEMSimpleLineGraph' 66 | 67 | DZNEmptyDataSet 68 | 提供图标空数据时的ui效果 69 | github:https://github.com/dzenbot/DZNEmptyDataSet 70 | pod 'DZNEmptyDataSet' 71 | 72 | 73 | ============网络================ 74 | AFNetworking 75 | https://github.com/AFNetworking/AFNetworking/ 76 | 77 | MKNetworkKit 2379 78 | https://github.com/MugunthKumar/MKNetworkKit 79 | 80 | Alamofire 81 | AFNetworking的小弟,swift版本 82 | 83 | ============图像处理============== 84 | SDWebImage 图片异步加载及缓存 85 | https://github.com/rs/SDWebImage 86 | 87 | UIImage+Resize 调整图片大小 88 | GitHub:https://github.com/coryalder/UIImage_Resize 89 | 提供多种方法为图片设置透明度、圆角、裁剪、调整大小等: 90 | 91 | ============下拉刷新============== 92 | SVPullToRefresh 下拉刷新、上拉加载更多 ====2740 93 | GitHub:https://github.com/samvermette/SVPullToRefresh 94 | 95 | MJRefresh https://github.com/CoderMJLee/MJRefresh ====839 96 | pod 'MJRefresh' 97 | 98 | PullToRefresh https://github.com/leah/PullToRefresh === 1950 99 | 100 | ================特效=========================== 101 | CSStickyHeaderFlowLayout :tableview 悬停的头部 102 | https://github.com/jamztang/CSStickyHeaderFlowLayout 103 | pod "CSStickyHeaderFlowLayout" 104 | 105 | Spring: 106 | https://github.com/MengTo/Spring 107 | pod 'Spring', '~> 1.0.3' 108 | 109 | ================数据操作=========================== 110 | FMDB 111 | 说明:使用sqllite封装的 112 | https://github.com/ccgus/fmdb 113 | pod 'FMDB' 114 | # pod 'FMDB/FTS' # FMDB with FTS 115 | # pod 'FMDB/standalone' # FMDB with latest SQLite amalgamation source 116 | # pod 'FMDB/standalone/FTS' # FMDB with latest SQLite amalgamation source and FTS 117 | # pod 'FMDB/SQLCipher' # FMDB with SQLCipher 118 | 119 | 120 | MagicalRecord 数据操作 121 | 说明:coredata代替品 CoreData封装的 122 | https://github.com/magicalpanda/MagicalRecord 123 | 使用参考:http://www.open-open.com/lib/view/open1386811475580.html 124 | 125 | 126 | 127 | ============加载进度或提示============== 128 | MBProgressHUD 129 | GitHub:https://github.com/matej/MBProgressHUD 130 | SVProgressHUD 提示效果 131 | GitHub:https://github.com/samvermette/SVProgressHUD 132 | ZAActivityBar 提示效果 133 | GitHub:https://github.com/zacaltman/ZAActivityBar 134 | ZAActivityBar 提示效果 135 | GitHub:https://github.com/zacaltman/ZAActivityBar 136 | 137 | ============ui组件============== 138 | PrettyKit 139 | GitHub:https://github.com/vicpenap/PrettyKit 140 | 定制了一些UI组件如UITableViewCell、UINavigationBar、UITabBar、UIToolBar等,比系统自带的更加美观。 141 | MGBox2 142 | GitHub:https://github.com/sobri909/MGBox2 143 | 提供一些定制的UI组件可以更简单快速的创建表格、网格布局,以及丰富的文本呈现,基于block的事件机制等,包含:MGBox、MGTableBox、MGTableBoxStyled、MGScrollView、MGButton、MGEvents、MGEasyFrame、MGLine等,其中MGBox还支持screenshot方法用于截图。 144 | 145 | Nimbus 146 | GitHub:https://github.com/jverkoey/nimbus 147 | 著名的框架,提供了一套非常丰富的UI组件,可以使开发变得更加简单、有效率。 148 | 149 | FlatUIKit 150 | GitHub:https://github.com/Grouper/FlatUIKit 151 | 扁平化设计的UI组件,类似于WP或者iOS7的风格。 152 | 153 | MUKMediaGallery 154 | GitHub:https://github.com/muccy/MUKMediaGallery 155 | 媒体库效果,支持图片、视频及音频。 156 | 157 | PTShowcaseViewController 158 | GitHub:https://github.com/exalted/PTShowcaseViewController 159 | 同样是一个媒体库效果,支持的格式更多,包括:图片、视频、PDF等. 160 | 161 | MWPhotoBrowser 162 | GitHub:https://github.com/mwaterfall/MWPhotoBrowser 163 | 图片展示效果,支持本地及远程的图片,使用也比较简单,只要实现MWPhotoBrowserDelegate协议: 164 | 165 | ios-image-filters 166 | GitHub:https://github.com/esilverberg/ios-image-filters提供多种图片滤镜效果。 167 | 168 | PDF Reader Core for iOS 169 | GitHub:https://github.com/vfr/Reader 170 | PDF阅读器核心。 171 | 172 | ios-image-filters 173 | GitHub:https://github.com/esilverberg/ios-image-filters提供多种图片滤镜效果。 174 | 175 | PDF Reader Core for iOS 176 | GitHub:https://github.com/vfr/Reader 177 | PDF阅读器核心。 178 | 179 | REMenu 180 | munu控件 181 | pod 'REMenu', '~> 1.10' 182 | 183 | 文本框 184 | HansPinckaers/GrowingTextView 185 | https://github.com/HansPinckaers/GrowingTextView 186 | pod 'HPGrowingTextView', '~> 1.1' 187 | 188 | MGSwipeTableCell 189 | https://github.com/MortimerGoro/MGSwipeTableCell 190 | 191 | ```` 192 | 193 | 引用地址: 194 | 195 | http://github.ibireme.com/github/list/ios/ 196 | 197 | http://www.csdn.net/article/2013-06-05/2815530-GitHub-iOS-open-source-projects-one 198 | 199 | http://blog.csdn.net/xiazailushang/article/details/9716043 200 | 201 | http://www.open-open.com/lib/view/open1406518312015.html 202 | 203 | http://www.cocoachina.com/ios/20150727/12720.html 204 | -------------------------------------------------------------------------------- /3_Other/aes128加密解密.md: -------------------------------------------------------------------------------- 1 | ## aes128加密解密方法 2 | 3 | 1:导入头文件,引入相关库 4 | 5 | ```` 6 | #import "Encryption.h" 7 | #import 8 | ```` 9 | 10 | 2: 两个NSData的扩展方法 11 | 12 | ````objc 13 | @implementation NSData (Encryption) 14 | 15 | - (NSData *)AES256ParmEncryptWithKey:(NSString *)key //加密 16 | { 17 | char keyPtr[kCCKeySizeAES256+1]; 18 | bzero(keyPtr, sizeof(keyPtr)); 19 | [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 20 | NSUInteger dataLength = [self length]; 21 | size_t bufferSize = dataLength + kCCBlockSizeAES128; 22 | voidvoid *buffer = malloc(bufferSize); 23 | size_t numBytesEncrypted = 0; 24 | CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, 25 | kCCOptionPKCS7Padding | kCCOptionECBMode, 26 | keyPtr, kCCBlockSizeAES128, 27 | NULL, 28 | [self bytes], dataLength, 29 | buffer, bufferSize, 30 | &numBytesEncrypted); 31 | if (cryptStatus == kCCSuccess) { 32 | return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 33 | } 34 | free(buffer); 35 | return nil; 36 | } 37 | 38 | - (NSData *)AES256ParmDecryptWithKey:(NSString *)key //解密 39 | { 40 | char keyPtr[kCCKeySizeAES256+1]; 41 | bzero(keyPtr, sizeof(keyPtr)); 42 | [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 43 | NSUInteger dataLength = [self length]; 44 | size_t bufferSize = dataLength + kCCBlockSizeAES128; 45 | voidvoid *buffer = malloc(bufferSize); 46 | size_t numBytesDecrypted = 0; 47 | CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 48 | kCCOptionPKCS7Padding | kCCOptionECBMode, 49 | keyPtr, kCCBlockSizeAES128, 50 | NULL, 51 | [self bytes], dataLength, 52 | buffer, bufferSize, 53 | &numBytesDecrypted); 54 | if (cryptStatus == kCCSuccess) { 55 | return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; 56 | } 57 | free(buffer); 58 | return nil; 59 | } 60 | ```` 61 | 62 | 简单说明: 63 | CCCrypt方法有一些要注意的参数,下面做了一下注释。 64 | 65 | 66 | ````objc 67 | CCCrypt(kCCDecrypt, //kCCDecrypt是解密,kCCEncrypt是加密 68 | kCCAlgorithmAES128, //算法 ase128 69 | kCCOptionPKCS7Padding | kCCOptionECBMode, //填充模式,比如使用ase128算法,要求数据最小长度是128bit,当数据没达到长度是的填充数据策略 70 | keyPtr, //密钥 71 | kCCBlockSizeAES128, //密钥大小 72 | NULL, //偏移量 73 | [self bytes], dataLength, //数据和数据长度 74 | buffer, bufferSize, &numBytesDecrypted); 返回数据 75 | ```` 76 | 77 | 了解更多,参考下面的连接 78 | 79 | [加密基础知识](http://www.jianshu.com/p/98610bdc9bd6) 80 | [iOS官方加密解密demo](https://developer.apple.com/library/content/samplecode/CryptoExercise/Listings/Classes_SecKeyWrapper_h.html) 81 | [Mac和 iOS下的对称和非对称加密算法的使用](http://blog.csdn.net/zhz459880251/article/details/50551463) 82 | [ase算法介绍](http://www.cnblogs.com/luop/p/4334160.html) 83 | 84 | -------------------------------------------------------------------------------- /3_Other/iOS使用sha.md: -------------------------------------------------------------------------------- 1 | http://www.jianshu.com/p/c5e09615f7d6 2 | http://stackoverflow.com/questions/7570377/creating-sha1-hash-from-nsstring 3 | 4 | ## objc使用sha 5 | > 需要导入头文件 `#import ` 6 | 7 | //方法一 8 | - (void)sha256Encode { 9 | const char *s=[@"Clear" cStringUsingEncoding:NSASCIIStringEncoding]; 10 | NSData *keyData=[NSData dataWithBytes:s length:strlen(s)]; 11 | 12 | //使用对应的CC_SHA1,CC_SHA256,CC_SHA384,CC_SHA512的长度分别是20,32,48,64 13 | uint8_t digest[CC_SHA256_DIGEST_LENGTH]={0}; 14 | //使用对应的CC_SHA256,CC_SHA384,CC_SHA512 15 | CC_SHA256(keyData.bytes, (CC_LONG)keyData.length, digest); 16 | NSData *out=[NSData dataWithBytes:digest length:CC_SHA256_DIGEST_LENGTH]; 17 | //转成字符串 18 | NSString *hash=[out description]; 19 | hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""]; 20 | hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""]; 21 | hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""]; 22 | } 23 | 24 | //方法二 25 | - (NSString *)sha1 26 | { 27 | NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding]; 28 | uint8_t digest[CC_SHA1_DIGEST_LENGTH]; 29 | 30 | CC_SHA1(data.bytes, data.length, digest); 31 | 32 | NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2]; 33 | 34 | for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) 35 | { 36 | [output appendFormat:@"%02x", digest[i]]; 37 | } 38 | 39 | return output; 40 | } 41 | 42 | ## objc使用md5 43 | 44 | -(NSString *) md5 45 | { 46 | const char *cStr = [self UTF8String]; 47 | unsigned char digest[CC_MD5_DIGEST_LENGTH]; 48 | CC_MD5( cStr, strlen(cStr), digest ); 49 | 50 | NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; 51 | 52 | for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) 53 | [output appendFormat:@"%02x", digest[i]]; 54 | 55 | return output; 56 | } -------------------------------------------------------------------------------- /3_Other/iOS设计模式.md: -------------------------------------------------------------------------------- 1 | ## 单例模式 2 | 3 | ### objc单例标准写法 4 | + (instancetype)sharedManager 5 | { 6 | static PhotoManager *sharedPhotoManager = nil; 7 | static dispatch_once_t onceToken; 8 | dispatch_once(&onceToken, ^{ 9 | sharedPhotoManager = [[PhotoManager alloc] init]; 10 | sharedPhotoManager->_photosArray = [NSMutableArray array]; 11 | }); 12 | return sharedPhotoManager; 13 | } 14 | 15 | ### swift单例标准写法 16 | 17 | ````swift 18 | 19 | class MyManager { 20 | static private let sharedInstance = MyManager() 21 | class var sharedManager : MyManager { 22 | return sharedInstance 23 | } 24 | } 25 | 26 | ```` 27 | 28 | 29 | ## 工厂方法 30 | 31 | ````objc 32 | //正确 33 | +(instancetype)factoryA{ 34 | return [[[self class]alloc]init]; 35 | } 36 | 37 | //错误 38 | +(id)factoryB{ 39 | return [[XXXXClass alloc]init]; 40 | } 41 | ```` 42 | 43 | 错误原因: 44 | - 主要在与返回值instancetype是安全类型,能更准确推断类型 45 | - ```` [[XXXXClass alloc]init] ```` 在子类使用时不能返回正确的子类类型,所以需要使用 ````[[[self class]alloc]init];```` 46 | -------------------------------------------------------------------------------- /3_Other/lldb调试.md: -------------------------------------------------------------------------------- 1 | ```` 2 | n/next:step over; 3 | s/step:step into; 4 | finish:step out; 5 | c/continue:goto next breakpoint; 6 | expr/expression:Evaluate a C/ObjC/C++ expression(动态执行C/ObjC/C++表达式); 7 | p/print/expr/expression:print as a C/C++ basic variable; 8 | po/expr -O/expression -O:Print as an Objective-C object; 9 | call:调用。其实上述p/po后接表达式(expression)也有调用的功能,一般只在不需要显式输出,或是无返回值时使用call,用于动态调试插入调用代码。 10 | bt(backtrace),打印当前调用堆栈(crash堆栈),“bt all”可打印所有thread的堆栈(相当于command+6的Debug Session Navigation)。 11 | image:可用于寻址,有多个组合命令,比较实用的一种用法是寻找栈地址对应的代码(行)位置。 12 | 13 | ```` 14 | 15 | 参考页面:http://www.cocoachina.com/ios/20141225/10761.html -------------------------------------------------------------------------------- /3_Other/plist所有的key说明.md: -------------------------------------------------------------------------------- 1 | 参考下面的连接地址,官网整理的最全pilst配置文件说明 2 | 3 | [Information Property List Key Reference](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW36) -------------------------------------------------------------------------------- /3_Other/xcode Code Snippets Library的使用.md: -------------------------------------------------------------------------------- 1 | > Code Snippets Library可以帮你保存常用的代码段或自动完成的代码段 2 | 3 | 4 | ## 新建和使用 5 | 6 | 以属性代码段为例: 7 | 8 | - 1:写代码 ```` @property (nonatomic, copy) NSString *<#name#>; ```` 9 | - 2:代码拖到左下侧的Code Snippets中,并设置Snippets信息 10 | - 3:输入步骤2中设置的completion shortcut,回车便可自动完成步骤1写的代码 11 | 12 | <#name#>:可以输入参数的地方 13 | 14 | ## 新建snippets的属性说明 15 | 16 | ```` 17 | 1.Title:Code Snippets的标题; 18 | 2.Summary:Code Snippets的描述文字; 19 | 3.Platform:可以使用Code Snippets的平台,有IOS/OS X/All三个选项 20 | 4.Language:可以在哪些语言中使用该Code Snippets 21 | 5.Completion Shortcut:出现代码的短字母 22 | 6.Completion Scopes:可以在哪些文件中使用当前Code Snippets,比如全部位置,头文件中等,当然可以添加多个支持的位置。 23 | 7.最后的一个大得空白区域是对Code Snippets的效果预览 24 | ```` 25 | 26 | ## snippets的备份 27 | 28 | 备份位置: ```` ~/Library/Developer/Xcode/UserData/CodeSnippets ```` 29 | 30 | 31 | ## 常用的snippets 32 | 33 | 我常用的snippets 34 | 35 | ```` 36 | 代码: __weak __typeof(self) weakSelf = self; 37 | 名称:weakify-snippet 38 | 快捷键:weakify-snippet 39 | 类型:code expression 40 | 41 | 代码:__strong __typeof(weakSelf) strongSelf = weakSelf; 42 | 名称:weakify-snippet 43 | 快捷键:weakify-snippet 44 | 类型:code expression 45 | 46 | ```` 47 | 48 | 更多xcode snippets 请看别人整理好的仓库,推荐一个最全的 [https://github.com/Xcode-Snippets/Objective-C](https://github.com/Xcode-Snippets/Objective-C) 49 | 50 | 51 | -------------------------------------------------------------------------------- /3_Other/xcode利用target实现多版本管理.md: -------------------------------------------------------------------------------- 1 | 在实际开发过程中,会有很多相似版本的app开发,相似的app和主app绝大多数功能相同, 这个时候如何最有效的处理多版本app的开发? 2 | 3 | 4 | 1:评估具体差异后确定是否拆分project还是通过拆分target 5 | 2:对于绝大多数功能相似的情况,采用多Target编译方案来实现更有效率。 6 | 3:如果使用拆分project,需要选择大小合适的粒度去抽取app的公共的功能模块。 7 | 8 | 9 | ## 多target在不修改代码的情况下如何解决版本差异 10 | > 思路主要是修改target的编译文件,同一个文件名去对应不同路径下的文件进行编译,这样做的好处就是无需改一行代码,通过设置target就可以做的不同target对应不同的代码和资源文件 11 | 12 | ### 修改资源文件引用 13 | 14 | 15 | 选择对应的target -> build phases -> copy bundle resouces 修改指定版本对应的图片路径。 16 | 17 | 通过这种方式能解决不同版本编译出来的appui界面对应的差异。 18 | 19 | 此外,修改还可以修改不同targets对应不同的图标icon和启动画面 20 | ```` 21 | 1:Asset xcassets -> App Icons & launch Images -> New Ios App Icon 22 | 2:general -> App Icons & launch Images -> 选择对应的icons和启动images 23 | ```` 24 | 25 | 26 | ### 修改源代码引用 27 | 28 | 选择对应的target -> build phases -> compile source 修改指定版本对应编译文件路径。 29 | 30 | 通过这种方式能解决不同版本编译出来的app代码的差异 31 | 32 | 也可以通过xcode属性菜单中选择文件所属的target,这种方式更快捷一些。 33 | 34 | 35 | ### 修改pch文件的引用 36 | 可以定义多个pch文件,并在target -> build setting -> prefix header,修改不同target对应的pch文件路径 37 | 38 | 39 | ### 其他 40 | 此外还可以设置target对应不同的项目和库文件,启动前脚本等方式,实现版本差异 41 | 42 | 43 | ## 修改代码解决版本差异 44 | > 这种方式解决不同target更直接,不用改动整个文件,只需要对应改动部分代码段就好了,我们利用xcode target中的preprocessor macros来实现. 45 | 46 | 选择对应的target -> build setting -> preprocessor macros,定义对应版本的宏,然后再代码中判断宏,处理不同代码逻辑。这种方式并不是常规做法,简单,最适合做开关控制。 47 | 48 | ### 例子 49 | 50 | 1:在preprocessor macros中添加一个键,IS_XG=1 51 | 2:在代码中判断是否有这个开关 52 | 53 | ````objc 54 | //打印ccsc版本信息 55 | #ifdef IS_XG 56 | NSLog(@"ccsc星光版本"); 57 | #else 58 | NSLog(@"不是ccsc星光版本"); 59 | #endif 60 | ```` 61 | 62 | 63 | 64 | ## 注意点 65 | 66 | - 1.当你将新文件添加到项目时,别忘了同时选择多个Targets,保持代码在两个版本中同步。 67 | - 2.如果你使用Cocoapods,别忘了将新的target添加到podfile。你可以使用 link_with来指定多个targets。你可以进一步查询Cocoapods documentation了解更多细节。你的podfile看起来应该像这样 68 | 69 | ```` 70 | platform :ios, '7.0' 71 | workspace 'xxx' 72 | link_with 'target1', 'target2' 73 | pod 'xxx' 74 | 75 | ```` 76 | -------------------------------------------------------------------------------- /3_Other/xcode常用快捷键整理.md: -------------------------------------------------------------------------------- 1 | 2 | cmd = Command ctrl = control sft = shift opt = Option * = click 3 | 4 | 5 | ## 好用的 6 | 7 | - 切换 辅助/标准 编辑 : cmd + 回车 / cmd + opt + 回车 8 | - 隐藏/打开 导航器 cmd + 0 | 隐藏/打开 单元区域 cmd + opt + 0 9 | - 查找: cmd + f 查找替换 cmd | opt +f 项目查找 cmd + sft + f 项目查找替换 cmd | sft + opt + f 查找文档 cmd + sft + / 10 | - 全屏 cmd + ctrl + f 11 | - 拼写检查 cmd + : 12 | - 焦点切换 cmd + j 13 | - 定位到导航栏 cmd + sft + j 14 | - 跳转到方法或代码的实现 cmd +ctrl + j 15 | - 清除控制台信息 cmd + k 16 | 17 | 18 | 19 | ## 常用且好记的 20 | 21 | - 快速打开 cmd+sft+o 22 | - 快速文档 opt+* or ** | 三指点击 23 | - 跳转至定义 cmd + * 24 | - .m和.h文件切换 cmd+ctrl + 上 or 下 25 | 26 | - 导航器面板切换 cmd + 1,2,3,4,5,6,7,8 27 | - 单元区域切换 cmd+opt + 1,2,3,4,5,6,7,8 28 | - 显示/隐藏调试区域 cmd + sft + Y / 焦点到输入控制台 cmd + sft + c 29 | - 添加/删除断点 cmd + \ 30 | - 激活/禁用全部断点 cmd + y 31 | - opt+cmd+r:编辑配置(Edit Scheme) 32 | 33 | 34 | 35 | ## 不常用的 36 | 37 | 38 | 39 | ## 代码编辑 40 | 41 | - 缩进 cmd + [ or ] 42 | - 注释 cmd + / 43 | - 匹配代码区域 :双击某个分隔符(如()、[]、{} 等) 44 | - 启动和停止 cmd + r | cmd + . 45 | - 在自定义尺寸导航到代码 cmd + sft + opt + * 46 | - 跳转到行 cmd + l 47 | 48 | ## 调试 49 | 50 | Command + R 运行。 51 | Command + . 停止 52 | F6单步调试、F7跳入,F8继续 53 | 54 | 55 | ## 快速预览图 56 | 57 | ![](../res/1418798425648696.png) 58 | ![](../res/1418798425343723.png) 59 | -------------------------------------------------------------------------------- /3_Other/xcode插件.md: -------------------------------------------------------------------------------- 1 | ## Alcatraz 2 | 3 | 作用:管理xcode插件 4 | 5 | 安装: 6 | 7 | 命令行执行: 8 | 9 | ```` curl -fsSL https://raw.github.com/supermarin/Alcatraz/master/Scripts/install.sh | sh ```` 10 | 11 | 删除: 12 | 13 | ````rm -rf ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/Alcatraz.xcplugin 14 | ```` 15 | 16 | 快捷键 command + shift + 9 17 | 18 | github地址:https://github.com/supermarin/Alcatraz 19 | 20 | 插件安装的路径:~/Library/Application Support/Developer/Shared/Xcode 21 | 22 | ## 插件安装 23 | 24 | 1:推荐! 使用Alcatraz安装,commannd + sift + 9 调出图形界面,然后使用搜索插件安装 25 | 26 | 2:手动安装:对应有些好的插件,Alcatraz找不到的话,可以手动下载插件包,然后安装。 27 | 28 | 安装方法:下载附件,解压后放在:你的用户/Library/Application Support/Developer/Shared/Xcode/Plug-ins目录 29 | 30 | ## 推荐插件 31 | 32 | #### 1:KSImageNamed 33 | 34 | Xcode资源文件在代码中添加只能感应,例如: [UIImage imageNamed: 会出现项目中的资源文件的智能感应 35 | 36 | #### 2:OMColorSense 37 | 38 | Xcode 代码中可以通过选择颜色生成uicolor代码 39 | 40 | 使用:先随便写个颜色,然后点击颜色行,改行的右上角会出现色快,点击可以选择颜色。或点击Xcode导航中的Edit-》insert color 41 | 42 | #### 3:VVDocumenter-Xcode 43 | 44 | Xcode 按三次斜杠(///)后自动生成方法的注释 45 | 46 | #### 4:fuzzyAutocomplete , 47 | 48 | 或是AutoresizeMask-for-Xcode加强版只能感应,只是模糊匹配,必装! 49 | 50 | #### 5:SCXcodeMiniMap 51 | 52 | 类似Sublime Text 右侧的迷你预览图 53 | 54 | #### 6:XToDo 55 | 56 | 代办列表管理 57 | 58 | 支持//TODO: //FIXME: //!!!: //???: 快捷键分别是 : control + shift + T ,control + shift + X ,control + shift + ! ,control + shift + Q 59 | 打开list 快捷键control + T 60 | 61 | #### 7:injectionforxcode 62 | 63 | 说明:动态修改app中的样式而不需要重新编译 64 | 65 | 教程:http://nonomori.farbox.com/post/injection-plugin-for-xcode 66 | 67 | 快捷键:control = :更新代码 68 | 69 | #### 8:XAlign 70 | 71 | 说明:自动对齐代码 72 | 73 | 快捷键:command+shift+X 74 | 75 | #### 9:Code Pilot 76 | 77 | xcode查找文件插件 78 | 79 | 快捷键:command+shift+X,建议替换为control+X 80 | 81 | #### 10:CocoaPods 82 | 83 | cocoaPods插件 84 | 85 | #### 11:Peckham 86 | 87 | 自动import头文件 88 | 89 | #### 12:Dash for Xcode 90 | 91 | xcode文档插件 92 | -------------------------------------------------------------------------------- /3_Other/先于main函数之前执行的代码段.md: -------------------------------------------------------------------------------- 1 | 2 | > __attribute__ 关键词可以定义一些先于活着后与main含住执行的代码 3 | 4 | 5 | __attribute__((constructor(PRIORITY))) 6 | 7 | 8 | ```` 9 | __attribute__( ( constructor ) ) static void Initializer() 10 | { 11 | static int isInitialized = 0; 12 | if( !isInitialized ) { 13 | isInitialized = 1; 14 | NSLog(@"Initializer"); 15 | } 16 | } 17 | ```` 18 | 19 | 20 | __attribute__((destructor(PRIORITY))) 21 | 22 | 23 | ```` 24 | __attribute__( ( constructor ) ) static void DeInitializer() 25 | { 26 | NSLog(@"DeInitializer"); 27 | } 28 | ```` -------------------------------------------------------------------------------- /3_Other/常见项目编译问题.md: -------------------------------------------------------------------------------- 1 | 2 | ## 错误 implicitly declaring library function 'strncpy' with type 3 | > [http://stackoverflow.com/questions/977233/warning-incompatible-implicit-declaration-of-built-in-function-xyz](http://stackoverflow.com/questions/977233/warning-incompatible-implicit-declaration-of-built-in-function-xyz) 4 | 5 | n C, using a previously undeclared function constitutes an implicit declaration of the function. In an implicit declaration, the return type is int if I recall correctly. Now, GCC has built-in definitions for some standard functions. If an implicit declaration does not match the built-in definition, you get this warning. 6 | 7 | To fix the problem, you have to declare the functions before using them; normally you do this by including the appropriate header. I recommend not to use the -fno-builtin-* flags if possible. 8 | 9 | Instead of stdlib.h, you should try 10 | 11 | ```` #include ```` 12 | 13 | That's where strcpy and strncpy are defined, at least according to the strcpy(2) man page. 14 | 15 | The exit function is defined in stdlib.h, though, so I don't know what's going on there. 16 | 17 | ## 错误 implicitly declaring library function 'objc_xxxxxx' with type .... 18 | > xxxx可以表示各种运行时错误 19 | 20 | 解决方法:添加头文件 21 | 22 | ````#import ```` -------------------------------------------------------------------------------- /3_Other/开发者账号和证书/AppStore发布成功后如何找到应用的下载地址.md: -------------------------------------------------------------------------------- 1 | ## 如何找到应用的下载地址: 2 | 3 | http://itunes.apple.com/cn/app/id111111 4 | 把id改成你自己应用的id就可以,应用id在itunesconnect里面申请之后就生成了 -------------------------------------------------------------------------------- /3_Other/开发者账号和证书/IOS 真机调试.md: -------------------------------------------------------------------------------- 1 | ## IOS 真机调试 2 | 3 | - 1:注册手机 uuid 4 | 选择Devices ,按步骤输入数据。 5 | 6 | - 2:创建Identifiers 7 | 输入Identifiers 选择权限 8 | 9 | - 3:创建电脑调试的证书 Certificates 10 | 根据自己电脑的钥匙串生成开发电脑需要的Certificates 11 | 12 | - 4: 创建手机调试的证书 Provisioning Profiles 13 | 根据申请好的,Identifiers,选择可以调试的电脑和设备,其实就是把开发环境和开发设备已经Identifiers三者进行绑定 14 | 15 | - 5: 推送和证书多机器开发需要用到.p12证书,导出方式: 16 | 选择 钥匙串 -> 左侧选择登陆和我的证书 ->右侧找到相应的证书后右键点击 -> 导出 -> 选择.p12 17 | 18 | ## 参考网站 19 | 20 | [iOS开发:创建真机调试证书](http://jingyan.baidu.com/article/ff411625b8141312e48237a7.html) 21 | -------------------------------------------------------------------------------- /3_Other/开发者账号和证书/Xcode因为证书问题常见错误.md: -------------------------------------------------------------------------------- 1 | ## Xcode因为证书问题常见错误 2 | 3 | ### ![](http://upload-images.jianshu.io/upload_images/200100-3a8214825f9927f2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 4 | 5 | Could not launch "xxxxxx" 6 | 7 | > process launch failed : security 8 | 9 | 确认下证书是不是开发证书,如果是发布证书就会出现这样的提示。 10 | 11 | 12 | ### ![](http://upload-images.jianshu.io/upload_images/200100-1a8238279a068561.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 13 | 14 | 证书失效了,去开发者中心重新生成一个 15 | 16 | ### ![](http://upload-images.jianshu.io/upload_images/200100-5a52f5d070a03ff4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 17 | 18 | 包标识符不与描述文件包含的包标识符不一致,按照它的提示换一下就好了,最好不要点 Fix Issue,点完后 Xcode 会自己生成一个包含统配包标识符的描述文件,并且 Remove 已经生成好的描述文件。会影响整个团队的合作。 19 | 20 | 21 | ### process launch failed: timed out trying to launch app 22 | 23 | 还是描述文件的问题,把发布的描述文件或者是 hoc 的描述文件当成开发描述文件使用了。stackoverflow的解释 24 | 25 | ### This application's application-identifier entitlement does not match that of the installed application. These values must match for an upgrade to be allowed. 26 | 27 | iPhone上已经装了包标识符一样的 App,删掉再运行。 28 | 29 | 30 | ### 没有找到报错的的图片和提示,我来描述一下那个情况:就是从开发者网站直接下载一个开发证书,然后选择了对应的描述文件,但是Xcode却不能选择那个下载的开发证书,然后如果运行会报错。原因是直接下载的开发证书不在在你机器上生成的,这时应该做的就是让生成证书的那个同学给你导出一个 p12 文件的开发证书,和证书的key,也是 p12 文件。或者你再申请一个开发者证书,再生成一个描述文件。 31 | 32 | 33 | ## 参考 34 | 35 | [Xcode因为证书问题经常报的那些错](http://www.jianshu.com/p/b10680a32d35) -------------------------------------------------------------------------------- /3_Other/开发者账号和证书/failed to locate or generate matching signing assets错误解决办法.md: -------------------------------------------------------------------------------- 1 | 2 | ![](./4F9EFDD7-E466-4BE3-8A50-DDC42C91E7E7) 3 | 4 | ## failed to locate or generate matching signing assets错误解决办法 5 | 6 | 1,按照你那个链接下载,[https://developer.apple.com/certificationauthority/AppleWWDRCA.cer](https://developer.apple.com/certificationauthority/AppleWWDRCA.cer),并安装。 7 | 8 | 2, 在“钥匙串”里选择“登录”,然后点选“证书”,在这个界面,选择工具栏的“显示” -> “显示过期证书”,这时候你会发现一个过期的“WWDR Certificate”(Apple Worldwide Developer Relations Certification Authority),删除它。 9 | 10 | 3, 在“系统”的那一栏也有这个过期的“WWDR Certificate”,一并删除它。 11 | 12 | 4 ,不出意外你的证书那里从 “This certificate has an invalid issuer”(此证书的签发者无效)变成了 “This certificate is valid”了。 -------------------------------------------------------------------------------- /3_Other/开发者账号和证书/企业app发布.md: -------------------------------------------------------------------------------- 1 | ## 步骤 2 | 3 | - 1:app绑定企业证书 4 | - 2:生成ipa和manifest.plist文件 5 | - 3:创建html连接,链接地址:itms-services://?action=download-manifest&url=https://xxx.com/apps/xxx.plist 6 | 7 | 过程网上很多,可以参考:最下方的参考 8 | 9 | 例如: 10 | ```` 11 | Install the In-House App 12 | ```` 13 | 14 | 15 | ## 注意 16 | - 生成连接时候需要四个个文件,分别是两个image和一个ipa,manifest文件 必须发布在https协议的域名下 17 | - 图片尺寸为:512x512 和 57x57 18 | - manifest.plist中ipa文件下载的地址必须使用http,而图片和manifest.plist文件则必须使用https地址(待验证) 19 | - https用的如果是自制证书,需要客户端先安装自制证书的.cer文件后才能正常下载安装ipa,否则会提示:无法连接到www.xx.com 20 | - 企业证书安装后用户首次打开时候必须点击授信,否则就需要到设置里面去设置证书授信,参考:[未受信任的企业级开发者](http://jingyan.baidu.com/article/335530da83801c19cb41c39f.html) 21 | 22 | 23 | ## 参考内容 24 | 25 | - [在企业内部分发 iOS 应用程序](http://www.cocoachina.com/industry/20140818/9401.html) 26 | - [iOS企业开发In House ipa发布流程](http://wenku.baidu.com/link?url=YzJkCMo8HggUbH-UGi6GVAa-_FuYavSG5C2eRPLLDXe6cZDmi5QbLg1HJuSUTcpfa6_MQVDtLO5AY9nS_4XjNXNEFDUvHnFqS_e7L-LKmEW) 27 | 28 | -------------------------------------------------------------------------------- /3_Other/开发者账号和证书/新版itunesconnect__App注册及申请、发布流程说明文档.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolnameismy/ios-tips/e2b79e6bc648ff8b16b54cbd303132dbdb242602/3_Other/开发者账号和证书/新版itunesconnect__App注册及申请、发布流程说明文档.pdf -------------------------------------------------------------------------------- /3_Other/推送服务/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using PushSharp; 6 | using PushSharp.Apple; 7 | using PushSharp.Core; 8 | using System.IO; 9 | 10 | 11 | namespace PushSharpConsole 12 | { 13 | class Program 14 | { 15 | [STAThread] 16 | static void Main(string[] args) 17 | { 18 | 19 | //Create our service 20 | var push = new PushBroker(); 21 | 22 | //Wire up the events 23 | push.OnNotificationSent += NotificationSent; 24 | push.OnNotificationFailed += NotificationFailed; 25 | 26 | //------------------------- 27 | // APPLE NOTIFICATIONS 28 | //------------------------- 29 | //Configure and start Apple APNS 30 | // IMPORTANT: Make sure you use the right Push certificate. Apple allows you to generate one for connecting to Sandbox, 31 | // and one for connecting to Production. You must use the right one, to match the provisioning profile you build your 32 | // app with! 33 | var appleCert = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../id4test_push_aps_development.p12")); 34 | //IMPORTANT: If you are using a Development provisioning Profile, you must use the Sandbox push notification server 35 | // (so you would leave the first arg in the ctor of ApplePushChannelSettings as 'false') 36 | // If you are using an AdHoc or AppStore provisioning profile, you must use the Production push notification server 37 | // (so you would change the first arg in the ctor of ApplePushChannelSettings to 'true') 38 | push.RegisterAppleService(new ApplePushChannelSettings(appleCert, "WEIWEI")); //Extension method 39 | //Fluent construction of an iOS notification 40 | //IMPORTANT: For iOS you MUST MUST MUST use your own DeviceToken here that gets generated within your iOS app itself when the Application Delegate 41 | // for registered for remote notifications is called, and the device token is passed back to you 42 | push.QueueNotification(new AppleNotification() 43 | .ForDeviceToken("cde6d75a0fc144b2bd30e10e15855376e4b53d793e6ccf9495787df19ace48d4") 44 | .WithAlert("Hello World!") 45 | .WithBadge(7) 46 | .WithSound("sound.caf")); 47 | //Console.ReadKey(); 48 | Console.ReadLine(); 49 | } 50 | static void NotificationSent(object sender, INotification notification) 51 | { 52 | Console.WriteLine("发送成功!"); 53 | Console.WriteLine("Sent: " + sender + " -> " + notification); 54 | } 55 | static void NotificationFailed(object sender, INotification notification, Exception notificationFailureException) 56 | { 57 | Console.WriteLine("发送失败!"); 58 | Console.WriteLine("Failure: " + sender + " -> " + notificationFailureException.Message + " -> " + notification); 59 | } 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /3_Other/推送服务/iOS消息推送实现.md: -------------------------------------------------------------------------------- 1 | # iOS消息推送实现 2 | 3 | ## 客户端 4 | 5 | ** 证书和权限的申请:*** 6 | 7 | - 1 :App必须要推送权限,申请真机测试权限 8 | - 2 :对应的appID申请推送证书 9 | - 3 :使用推送证书到处P12证书给服务器使用 10 | 11 | ## 客户端代码实现: 12 | 13 | - 1:建立我们的推送的项目(注意BundleIdentifier必须和我们推送应用的App id一致) 14 | 15 | - 2:在AppDelegate里didFinishLaunchingWithOptions函数里写 16 | 17 | ````objc 18 | - (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions 19 | { 20 | …… 21 | //推送的形式:标记,声音,提示 22 | [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert]; 23 | return YES; 24 | } 25 | 26 | 27 | - (void)application:(UIApplication *)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken { 28 | NSLog(@"regisger success:%@",pToken); 29 | //注册成功,将deviceToken保存到应用服务器数据库中 30 | } 31 | - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{ 32 | // 处理推送消息 33 | NSLog(@"userinfo:%@",userInfo); 34 | 35 | NSLog(@"收到推送消息:%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]); 36 | } 37 | - (void)application:(UIApplication *)applicationdidFailToRegisterForRemoteNotificationsWithError:(NSError *)error { 38 | NSLog(@"Registfail%@",error); 39 | } 40 | 41 | ```` 42 | 43 | ## 服务器端 44 | > 服务端开发的思路都差不多,使用第三方封装好的包,这个包如果自己写还是很麻烦的。 45 | > 这里以[pushSharp](https://github.com/Redth/PushSharp) 为例,一个开源的c#推送代码 46 | 47 | 关键代码说明: 48 | 49 | ````c# 50 | 51 | var appleCert = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../id4test_push_aps_development.p12"));//证书位置 52 | //IMPORTANT: If you are using a Development provisioning Profile, you must use the Sandbox push notification server 53 | // (so you would leave the first arg in the ctor of ApplePushChannelSettings as 'false') 54 | // If you are using an AdHoc or AppStore provisioning profile, you must use the Production push notification server 55 | // (so you would change the first arg in the ctor of ApplePushChannelSettings to 'true') 56 | push.RegisterAppleService(new ApplePushChannelSettings(appleCert, "WEIWEI")); //Extension method 57 | //Fluent construction of an iOS notification 58 | //IMPORTANT: For iOS you MUST MUST MUST use your own DeviceToken here that gets generated within your iOS app itself when the Application Delegate 59 | // for registered for remote notifications is called, and the device token is passed back to you 60 | push.QueueNotification(new AppleNotification() 61 | .ForDeviceToken("cde6d75a0fc144b2bd30e10e15855376e4b53d793e6ccf9495787df19ace48d4")//手机设备token 62 | .WithAlert("Hello World!") 63 | .WithBadge(7) 64 | .WithSound("sound.caf")); 65 | ```` -------------------------------------------------------------------------------- /3_Other/根据不同ios版本实现不同逻辑.md: -------------------------------------------------------------------------------- 1 | ## objc 2 | 3 | ````objc 4 | #if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_8_0 5 | // iOS 8或更高版本 6 | #else 7 | // iOS8之前的版本 8 | #endif 9 | ```` 10 | 11 | 12 | ## swift 13 | 14 | 15 | ````swift 16 | 17 | if #available(iOS 8, *) { 18 | // iOS 8或更高版本 19 | 20 | } else { 21 | // iOS8之前的版本 22 | 23 | } 24 | 25 | ```` -------------------------------------------------------------------------------- /3_Other/编码习惯.md: -------------------------------------------------------------------------------- 1 | 2 | ## 美化代码 3 | - 只使用空格而不要使用tab,且一次缩进两个空格。应该将xcode设置成自动将制表符替换成空格,缩进为2空格 4 | - 方法的大括号和其他的大括号(if/else/switch/while 等) 总是在同一行开始,在新起一行结束 5 | - 尽量让你的代码保持在 80 列之内,通过设置 Xcode > Preferences > Text Editing > Show page guide,来使越界更容易被发现。 6 | - if语句不要省略{ } 7 | - 方法名与方法类型 (-/+ 符号)之间应该以空格间隔 8 | - @public 和 @private 访问修饰符应该以一个空格缩进。 9 | - 方法的调用要么所有参数一行,要么每个参数一行且保证冒号都对其,当第一个关键字比其它的短时,保证下一行至少有 4 个空格的缩进 10 | 11 | ## 最佳实践 12 | - 不要使用尤达表达式 13 | 14 | ````objc 15 | //尤达是星球大战中的jidi武师,他说话的语法都是很奇怪的倒装句,这里泛指这样的代码 16 | if ([@8 isEqual:a]) // 错误 17 | if ([a isEqual:@8]) // 正确 18 | ```` 19 | - 不要和YES,NO,Nil这些值做比较 20 | 21 | ````objc 22 | if (great == YES) //错误 23 | if (great) //正确 24 | ```` 25 | - 不过过度使用if嵌套,有时可以用return减少if嵌套 26 | 27 | ````objc 28 | - (void)someMethod { 29 | if (![someOther boolValue]) { 30 | return; 31 | } 32 | //Do something important 33 | } 34 | ```` 35 | - 复杂的表达式应该拆分多个语义更明确的字句 36 | - 三元运算符 ? 应该只用在它能让代码更加清楚的地方 37 | - 注意stong,weak,copy,assign的正确使用 38 | - 尽量避免使用c的基本类型 ,例如: 39 | 40 | ````objc 41 | int -> NSInteger 42 | unsigned -> NSUInteger 43 | float -> CGFloat 44 | 动画时间 -> NSTimeInterval 45 | enum -> NS_ENUM 46 | ```` 47 | - 合理使用参数断言,当特定参数的条件不满足时,使用 ```` NSParameterAssert()```` 来断言条件是否成立或是抛出一个异常 48 | - 工厂方法或类构造器方法,返回类型需要使用instancetype而不要用id类型,方法中需要使用 [[xxx class]alloc] init]方法构造对象而不要用[[XXXClass alloc]init] 49 | - 永远不要在```` init dealloc ````方法中使用 getter,setter,.属性等,你应当直接访问实例变量 50 | - 类的构成方法(init方法)需要遵守Designated Secondary原则。这点在swift中被强制规定init和convenience构造方法。 51 | 52 | ```` 53 | designated 初始化方法一般提供所有的参数,有且只有一个,而secondary 初始化方法是一个或多个,并且提供一个或者更多的默认参数来调用 designated初始化方法 54 | ```` 55 | - 定义你的 designated initializer,确保调用了直接超类的 designated initializer。 56 | - 重载直接超类的 designated initializer。调用你的新的 designated initializer。 57 | - 为新的 designated initializer 写文档。 58 | - 永远不从 designated initializer 里面调用一个 secondary initializer 59 | - 注意初始化模式的合理使用(类簇,单例) 60 | - 合理使用懒加载Lazy loading 61 | 62 | ```` 63 | 当实例化一个对象需要耗费很多资源,或者配置一次就要调用很多配置相关的方法而你又不想弄乱这些方法时,我们需要重写 getter 方法以延迟实例化 64 | ```` 65 | - 要重写类的相等性时,需要同时实现isEqual和hash方法 66 | - 常量推荐静态常量的声明,如果要暴露给外部,使用extern关键词,例如: 67 | 68 | ````objc 69 | extern NSString *const ZOCCacheControllerDidClearCacheNotification; 70 | static NSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification"; 71 | ```` 72 | - 定义你自己的 NSNotification 的时候你应该把你的通知的名字定义为一个字符串常量 73 | 74 | ````objc 75 | // Foo.h 76 | extern NSString * const ZOCFooDidBecomeBarNotification 77 | // Foo.m 78 | NSString * const ZOCFooDidBecomeBarNotification = @"ZOCFooDidBecomeBarNotification"; 79 | ```` 80 | - objc中可以合理使用代码块的特性,使局部变量更清晰 81 | 82 | ````objc 83 | //代码块如果在闭合的圆括号内的话,会返回最后语句的值 84 | NSURL *url = ({ 85 | NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, endpoint]; 86 | [NSURL URLWithString:urlString]; 87 | }); 88 | ```` 89 | - 合理使用Pragma Mark区分:不同功能组的方法,protocols 的实现,对父类方法的重写,View 的生命周期,自定义访问器, 90 | - 方法注释最好用/** 开头,换行后第一句写方法的一句话描述,空一行后在写余下的描述, 91 | 还可以使用 | 来引用注释中的变量名及符号名而不是使用引号,例如 92 | ```` // Sometimes we need |count| to be less than zero. ```` 93 | 94 | - 函数定义中的block参数应该尽量放到最后一个参数,把需要提供的数据和错误信息整合到一个单独 block 中,比分别提供成功和失败的 block 要好 95 | 96 | ````objc 97 | - (void)downloadObjectsAtPath:(NSString *)path 98 | completion:(void(^)(NSArray *objects, NSError *error))completion; 99 | ```` 100 | - 函数定义中的error参数,尽可能方法函数的最后一个函数,并且遵循,数据为空,那么error不为nil,和error不为空,数据必须为空 101 | - block合理的使用self,weakself,strongSelf 102 | 103 | ```` 104 | 一般来说:如果block不是属性则使用self,是属性但block中调用单个self的方法时用weakSelf,多个方法用strongSelf 105 | ```` 106 | - block如果一行可以写完块,则没必要换行,块内的代码须按 4 空格缩进,果块太长,比如超过 20 行,建议把它定义成一个局部变量,然后再使用该变量, 107 | - 不要使用new方法创建对象 108 | 109 | 110 | ## 命名规范 111 | ### 方法的命名: 112 | - 不要使用and连接参数,第一个参数可以用with,若有动词可以使用for,委托用did,will表示状态 113 | - 如果方法表示让对象执行一个动作,使用动词打头来命名 114 | - category方法前加上自己的小写前缀以及下划线,比如- (id)zoc_myCategoryMethod 115 | - 方法的定义,当一行有非常多的参数,更好的方式是将每个参数单独拆成一行。如果使用多行,将每个参数前的冒号对齐,当第一个关键字比其它的短时,保证下一行至少有 4 个空格的缩进 116 | 117 | ### 类,协议命名 118 | - 类名应该以三个大写字母作为前缀(双字母前缀为 Apple 的类预留),首字母大写 119 | - 方法名首字母小写 120 | - 变量名首字母小写,私有变量名称可以用"_"作为后缀,例如```` myInstanceVariable_ ```` 121 | - 常量命名可以使用字母'k'作为前缀 122 | - 子类命名应该把说明性的部分放在前缀和父类名的在中间,例如```` ZOCNetworkClient => ZOCTwitterNetworkClient ```` 123 | 124 | ### 属性 125 | - 属性应该尽可能的描述性地命名,避免缩写,并且小写字母开头的驼峰命名。 *符号要靠近名称,如```` NSString *text ```` 126 | - 属性尽可能使用.符号调用 127 | - 属性定义排列顺序:原子性,读写性,内存管理,例如 ```` @property (nonatomic, readwrite, copy) NSString *name; ```` 128 | - 私有属性定义在实现文件中。 129 | 130 | ```` 131 | ## 参考 132 | - [objc禅翻译](https://github.com/oa414/objc-zen-book-cn/) 133 | - [Google 开源项目风格指南 - objc](http://zh-google-styleguide.readthedocs.org/en/latest/google-objc-styleguide/contents/) 134 | -------------------------------------------------------------------------------- /3_Other/预编译/iOS预编译pch文件的使用.md: -------------------------------------------------------------------------------- 1 | ## IOS预编译pch文件的使用 2 | 3 | 意义:可以加快项目编译速度,常用的很少修改的方法和头文件放在里面比较好 4 | 5 | 加入方法:添加新文件-其他-PCH文件 6 | 7 | 配置预编译: 8 | 9 | ```` 10 | Bulid settings -- Apple LLVM 6.0 - Language 11 | 1:Percompile Prefix Header 设置为YES 12 | 2: Prefix Header 设置为: $(SRCROOT)/{路径名}/{文件名}.pch 13 | 14 | $(SRCROOT)/{PlantAssistant}/PrefixHeader.pch 15 | 16 | ```` -------------------------------------------------------------------------------- /3_Other/预编译/ios宏的使用.md: -------------------------------------------------------------------------------- 1 | ## 替换字符 2 | --- 3 | 4 | ````objc 5 | #define M_PI 3.14159265358979323846264338327950288 6 | ```` 7 | 8 | ## 简单函数宏 9 | --- 10 | ````objc 11 | //定义: 12 | #define add(a,b) a+b 13 | //使用: 14 | add(1,2) //打印3 15 | ```` 16 | 17 | ## 复杂函数宏 18 | --- 19 | 之前的内容很容易明白了对吧,不过复杂的函数宏就没那么容易明白了。先看一下宏中的一些常用的特殊符号和系统方法 20 | 21 | ````objc 22 | //关键字 23 | ...:可变参数 24 | __VA_ARGS__ :宏定义中的...中的所有剩余参数 25 | ##:连接符号 26 | #:原样输出 27 | /:换行符 28 | 29 | //系统工具方法 30 | __COUNTER__ 无重复的计数器,从程序启动开始每次调用都会++,常用语宏中定义无重复的参数名称 31 | __FILE__:当前文件的绝对路径,常见于log中 32 | __LINE__:展开该宏时在文件中的行数,常见于log中 33 | __func__:所在scope的函数名称,常见于log中 34 | 35 | ```` 36 | 37 | 复杂宏会用到 ````#,##,...,__VA_ARGS__````等关键字和系统方法,这些关键字组合可以实现一些技巧,比如换参数和换方法名等等,多个宏结合使用,完成一些高级的功能.接下来演示的,用来获取方法参数宏(10个参数以内) 38 | 39 | ````objc 40 | /* 41 | 获取方法参数的宏bb_argcount() 42 | 它的好处不仅将计算在预处理时搞定,不拖延到运行时的cpu;更重要的是编译检查。如某些可变参数的要求2个或3个参数,其他的都不行。只有这样的宏才能在编译前就确定参数是否满足要求 43 | 参数分类很多步骤,通过不懂的替换宏名称和参数,从而达到计算出方法参数个数的功能。 44 | */ 45 | #define bb_argcount(...) bb_at(10, __VA_ARGS__,10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 46 | #define bb_at(N,...) bb_concat_at##N (__VA_ARGS__) 47 | #define bb_concat_at10(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,...) bb_head(__VA_ARGS__) 48 | #define bb_head(...) bb_head_first(__VA_ARGS__,0) 49 | #define bb_head_first(first,...) first 50 | 51 | 52 | //调用示例: 53 | int count = bb_argcount(a,b,c,d,e); 54 | NSLog(@" count is :%d",count); 55 | //输出: count is :5 56 | ```` 57 | 58 | 是不是很神奇?下来来一步步分析下具体如何实现的。 59 | 60 | ````objc 61 | bb_argcount(a,b,c,d,e);//假设我们传入5个参数 62 | ```` 63 | 64 | 步骤1:带入bb_argcount 65 | 66 | ````objc 67 | //#define bb_argcount(...) bb_at(10, __VA_ARGS__,10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 68 | //请注意...和__VA_ARGS__的使用,...是可变参数,传入的是a,b,c,d,e会替换__VA_ARGS__的部分,得到如下部分 69 | int count = bb_at(10, a, b, c, d, e, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 70 | ```` 71 | 72 | 步骤2:接下来带入bb_at 73 | 74 | ````objc 75 | //#define bb_at(N,...) bb_concat_at##N (__VA_ARGS__) 76 | //第一个参数为N,之后都是可变参数,所以N为10,__VA_ARGS__ 为 a, b, c, d, e, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 77 | //##是把字符连接起来,通过##我们重新使用了新的宏,这里就是bb_concat_at10 78 | //这一步即修改了参数,又修改了方法名 79 | int count = bb_concat_at10(a, b, c, d, e, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 80 | ```` 81 | 82 | 步骤3:带入bb_concat_at_10 83 | 84 | ````objc 85 | //bb_concat_at10(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,...) bb_head(__VA_ARGS__) 86 | //把前面10个参数都换了,第10位以后的参数设为可变参数 87 | int count = bb_head(5,4,3, 2, 1) 88 | ```` 89 | 90 | 步骤4:带入bb_head 91 | 92 | ````objc 93 | //bb_head(first,...) first 94 | //直接获取第一个数,其他的省略 95 | int count = 5; 96 | ```` 97 | 98 | 通过4步,就得到了想要的结果,是不是很神奇,很有意思?宏还有许多其他高级的用法,大家可以看一下[ReactiveCocoa](https://github.com/ReactiveCocoa),这个库源码里的宏写的非常多,有很多很有意思的宏。 99 | 100 | 101 | # 宏的健壮性 102 | > 宏虽然定义和使用很简单,但是想用好,想把宏定义的健壮不出bug,却不是那么容易。 103 | 104 | ````objc 105 | #define MIN(A,B) A < B ? A : B 106 | ```` 107 | 108 | 这个宏的作用是返回小的那个数,这个宏会有什么问题?我来列出可能导致这个宏出错的几种情况 109 | 110 | ````objc 111 | //exp1 112 | int a = 2 * MIN(3, 4); 113 | //exp2 114 | int a = MIN(3, 4 < 5 ? 4 : 5); 115 | //exp3 116 | float a = 1.0f; 117 | float b = MIN(a++, 1.5f); 118 | 119 | ```` 120 | 为什么会出错?大家把参数带入到宏里面展开就知道了。详细展开我也不说了,大家看我下面参考中的那篇文章,里面有详细过程。 121 | 122 | 来给出系统的标准定义,看,没那么容易实现吧。 123 | 124 | ````objc 125 | #if !defined(MIN) 126 | #define __NSMIN_IMPL__(A,B,L) ({ __typeof__(A) __NSX_PASTE__(__a,L) = (A); __typeof__(B) __NSX_PASTE__(__b,L) = (B); (__NSX_PASTE__(__a,L) < __NSX_PASTE__(__b,L)) ? __NSX_PASTE__(__a,L) : __NSX_PASTE__(__b,L); }) 127 | #define MIN(A,B) __NSMIN_IMPL__(A,B,__COUNTER__) 128 | #endif 129 | ```` 130 | 131 | 132 | ##如何查看宏的展开内容? 133 | --- 134 | 135 | 如果大家看这些宏看起来很吃力的话可以用下面这个````LOG_MACRO````查看宏的内容.宏的展开顺序为先完全展开宏参数,再扫描宏展开后里面的宏,如此反复。但是,宏内容中含有#和##这两个符号的时候,参数不会被先展开。 136 | 137 | ````objc 138 | //打印宏展开后的函数 139 | #define __toString(x) __toString_0(x) 140 | #define __toString_0(x) #x 141 | #define LOG_MACRO(x) NSLog(@"%s=\n%s", #x, __toString(x)) 142 | ```` 143 | 144 | ##优缺点 145 | --- 146 | 147 | 宏的优点: 148 | 149 | - 最主要还是帮你省点事,少写点代码。 150 | - 实现一些高级的功能 151 | 152 | 缺点 153 | 154 | - swift不支持 155 | - 名称没起好很容易造成歧义 156 | - 代码不是很易读 157 | - 宏没写好容易导致未知的bug 158 | 159 | 160 | =========== 161 | 162 | 参考文章: 163 | [宏定义的黑魔法 - 宏菜鸟起飞手册](http://onevcat.com/2014/01/black-magic-in-macro/) 164 | -------------------------------------------------------------------------------- /4_Study/ios学习技术栈.md: -------------------------------------------------------------------------------- 1 | ## ios学习技术栈 2 | 3 | ![image](https://raw.githubusercontent.com/shaojiankui/iOS-Route/master/look.jpg) 4 | 5 | 转自:https://github.com/shaojiankui/iOS-Route -------------------------------------------------------------------------------- /4_Study/ios学习网站.md: -------------------------------------------------------------------------------- 1 | ## ios技术网站 2 | --- 3 | - [cocoachina](http://www.cocoachina.com/) 4 | - [nshipster](http://nshipster.cn/) 5 | - [nshipster](http://nshipster.cn/) 6 | - [appcoda](http://www.appcoda.com/) 7 | - [伯乐在线](http://blog.jobbole.com) 8 | 9 | 10 | ## 技术博客 11 | --- 12 | 13 | - [sunnyxx](http://blog.sunnyxx.com/) 14 | - [刘彦玮的技术博客](http://liuyanwei.jumppo.com) | 15 | - [念茜的博客](http://nianxi.net/) | 16 | - [iwangke](http://www.iwangke.me/) | 17 | - [OneV's Den](http://onevcat.com) | 18 | - [破船之家](http://beyondvincent.com) | 19 | - [NSHipster](http://nshipster.cn) | 20 | - [Limboy 无网不剩](http://blog.leezhong.com/) | 21 | - [唐巧的技术博客](http://blog.devtang.com) | 22 | - [Lex Tang](http://lexrus.com/) | 23 | - [念茜的博客](http://nianxi.net) | 24 | - [Xcode Dev](http://blog.xcodev.com) | 25 | - [Ted's Homepage](http://wufawei.com/)| 26 | - [txx's blog](http://blog.t-xx.me) | 27 | - [sunnyxx的技术博客](http://blog.sunnyxx.com/) | 28 | - [Kevin Blog](http://zhowkev.in) | 29 | - [阿毛的蛋疼地](http://www.xiangwangfeng.com) | 30 | - [亚庆的 Blog](http://billwang1990.github.io) | 31 | - [Nonomori](http://nonomori.farbox.com) | 32 | - [言无不尽](http://tang3w.com) | 33 | - [Wonderffee's Blog](http://wonderffee.github.io) | 34 | - [I'm TualatriX](http://imtx.me) | 35 | - [Cocoabit](http://blog.cocoabit.com) | 36 | - [nixzhu on scriptogr.am](http://nixzhu.me) | 37 | - [不会开机的男孩](http://studentdeng.github.io) | 38 | - [Nico](http://blog.inico.me) | 39 | - [阿峰的技术窝窝](http://hufeng825.github.io) | 40 | - [answer_huang](http://answerhuang.duapp.com) | 41 | - [webfrogs](http://blog.nswebfrog.com/) | 42 | - [代码手工艺人](http://joeyio.com) | 43 | - [Lancy's Blog](http://gracelancy.com) | 44 | - [I'm Allen](http://www.imallen.com) | 45 | - [Travis' Blog](http://imi.im/)| 46 | - [王中周的技术博客](http://wangzz.github.io/) | 47 | - [会写代码的猪](http://jiajun.org/) | 48 | - [克伟的博客](http://wangkewei.cnblogs.com/) | 49 | - [摇滚诗人](http://cnblogs.com/biosli) | 50 | - [Luke's Homepage](http://geeklu.com/) | 51 | - [萧宸宇](http://iiiyu.com/) | 52 | - [Yuan博客](http://www.heyuan110.com/) | 53 | - [Shining IO](http://shiningio.com/) | 54 | - [YIFEIYANG--易飞扬的博客](http://www.yifeiyang.net/) | 55 | - [KooFrank's Blog](http://koofrank.com/) | 56 | - [hello it works](http://helloitworks.com) | 57 | - [码农人生](http://msching.github.io/) | 58 | - [玉令天下的Blog](http://yulingtianxia.com) | 59 | - [不掏蜂窝的熊](http://www.hotobear.com/) | 60 | - [猫·仁波切](https://andelf.github.io/) | 61 | - [煲仔饭](http://ivoryxiong.org/) | 62 | - [里脊串的开发随笔](http://adad184.com) | 63 | - [Chun Tips](http://chun.tips/)| 64 | - [Why's blog - 汪海的实验室](http://blog.callmewhy.com/) | 65 | - [土土哥的技术Blog](http://tutuge.me/) | 66 | - [庞海礁的个人空间 ](http://www.olinone.com/) | 67 | - [Casa Taloyum](http://casatwy.com/) | 68 | - [Kenshin Cui's Blog](http://www.cnblogs.com/kenshincui/) | 69 | - [技术哥的博客](http://suenblog.duapp.com/) | 70 | - [老谭笔记](http://www.tanhao.me/) | 71 | - [coderyi](http://www.coderyi.com/)| 72 | - [雷纯锋的技术博客](http://blog.leichunfeng.com) | 73 | - [iOS技术周报](http://weekly.ios-wiki.com) 74 | 75 | 76 | ## 原文博客 77 | --- 78 | - [holko](http://holko.pl/archive) 79 | - [krakendev](http://krakendev.io) 80 | 81 | ## 工具 82 | --- 83 | 84 | -(oc代码转swift工具)[https://objectivec2swift.com/#/converter/code] 85 | 86 | -------------------------------------------------------------------------------- /4_Study/好文阅读推荐.md: -------------------------------------------------------------------------------- 1 | 2 | - [iOS - 采用现代化的Objective-C](http://www.jianshu.com/p/934d72dab616) | [原文](https://developer.apple.com/library/ios/releasenotes/ObjectiveC/ModernizationObjC/AdoptingModernObjective-C/AdoptingModernObjective-C.html) 3 | 4 | - [禅与 Objective-C 编程艺术 (Zen and the Art of the Objective-C Craftsmanship 中文翻译)](https://github.com/oa414/objc-zen-book-cn/) 5 | 6 | - []() 7 | - []() 8 | - []() 9 | - []() 10 | - []() 11 | - []() 12 | - []() 13 | - []() 14 | - []() 15 | - []() 16 | - []() 17 | - []() 18 | - []() 19 | - []() 20 | - []() 21 | - []() 22 | - []() 23 | - []() 24 | - []() -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 刘彦玮 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [ios-tips](https://github.com/coolnameismy/ios-tips)是ios开发当中常用遇到的问题和解决方法的收集,包括ios和swif。 2 | 一共包括4个部分 3 | 4 | 5 | - 0_Foundation :基础 6 | - 1_UIKit :UIKit和界面相关 7 | - 2_ThirdParty :第三方控件 8 | - 3_Other :其他 9 | - iOS学习资源 10 | 11 | 欢迎大家给ios-tips补充内容。 12 | 13 | ## 补充要求 14 | 1. 格式是md 15 | 2. tips都很简短,不要涉及复杂的原理和方法 16 | 17 | ## 其他资源 18 | 19 | - iOS问题已经单独整理为[iOS-tips](https://github.com/coolnameismy/ios-tips) 20 | - 有些复杂的问题和开发技巧可以见 [刘彦玮的技术博客](http://liuyanwei.jumppo.com/) 21 | - 博客中的demo:[iOS-demo](https://github.com/coolnameismy/demo) | [web前端demo](https://github.com/coolnameismy/demo-web) 22 | 23 | 24 | ## 使用技巧 25 | 26 | 按 T 可以进入搜索页面,查找你需要的内容 27 | 28 | -------------------------------------------------------------------------------- /ios学习网站.md: -------------------------------------------------------------------------------- 1 | ## ios技术网站 2 | --- 3 | - [cocoachina](http://www.cocoachina.com/) 4 | - [nshipster](http://nshipster.cn/) 5 | - [nshipster](http://nshipster.cn/) 6 | - [appcoda](http://www.appcoda.com/) 7 | - [伯乐在线](http://blog.jobbole.com) 8 | 9 | 10 | ## 技术博客 11 | --- 12 | 13 | - [刘彦玮的技术博客](http://liuyanwei.jumppo.com) | 14 | - [念茜的博客](http://nianxi.net/) | 15 | - [iwangke](http://www.iwangke.me/) | 16 | - [OneV's Den](http://onevcat.com) | 17 | - [破船之家](http://beyondvincent.com) | 18 | - [NSHipster](http://nshipster.cn) | 19 | - [Limboy 无网不剩](http://blog.leezhong.com/) | 20 | - [唐巧的技术博客](http://blog.devtang.com) | 21 | - [Lex Tang](http://lexrus.com/) | 22 | - [念茜的博客](http://nianxi.net) | 23 | - [Xcode Dev](http://blog.xcodev.com) | 24 | - [Ted's Homepage](http://wufawei.com/)| 25 | - [txx's blog](http://blog.t-xx.me) | 26 | - [sunnyxx的技术博客](http://blog.sunnyxx.com/) | 27 | - [Kevin Blog](http://zhowkev.in) | 28 | - [阿毛的蛋疼地](http://www.xiangwangfeng.com) | 29 | - [亚庆的 Blog](http://billwang1990.github.io) | 30 | - [Nonomori](http://nonomori.farbox.com) | 31 | - [言无不尽](http://tang3w.com) | 32 | - [Wonderffee's Blog](http://wonderffee.github.io) | 33 | - [I'm TualatriX](http://imtx.me) | 34 | - [Cocoabit](http://blog.cocoabit.com) | 35 | - [nixzhu on scriptogr.am](http://nixzhu.me) | 36 | - [不会开机的男孩](http://studentdeng.github.io) | 37 | - [Nico](http://blog.inico.me) | 38 | - [阿峰的技术窝窝](http://hufeng825.github.io) | 39 | - [answer_huang](http://answerhuang.duapp.com) | 40 | - [webfrogs](http://blog.nswebfrog.com/) | 41 | - [代码手工艺人](http://joeyio.com) | 42 | - [Lancy's Blog](http://gracelancy.com) | 43 | - [I'm Allen](http://www.imallen.com) | 44 | - [Travis' Blog](http://imi.im/)| 45 | - [王中周的技术博客](http://wangzz.github.io/) | 46 | - [会写代码的猪](http://jiajun.org/) | 47 | - [克伟的博客](http://wangkewei.cnblogs.com/) | 48 | - [摇滚诗人](http://cnblogs.com/biosli) | 49 | - [Luke's Homepage](http://geeklu.com/) | 50 | - [萧宸宇](http://iiiyu.com/) | 51 | - [Yuan博客](http://www.heyuan110.com/) | 52 | - [Shining IO](http://shiningio.com/) | 53 | - [YIFEIYANG--易飞扬的博客](http://www.yifeiyang.net/) | 54 | - [KooFrank's Blog](http://koofrank.com/) | 55 | - [hello it works](http://helloitworks.com) | 56 | - [码农人生](http://msching.github.io/) | 57 | - [玉令天下的Blog](http://yulingtianxia.com) | 58 | - [不掏蜂窝的熊](http://www.hotobear.com/) | 59 | - [猫·仁波切](https://andelf.github.io/) | 60 | - [煲仔饭](http://ivoryxiong.org/) | 61 | - [里脊串的开发随笔](http://adad184.com) | 62 | - [Chun Tips](http://chun.tips/)| 63 | - [Why's blog - 汪海的实验室](http://blog.callmewhy.com/) | 64 | - [土土哥的技术Blog](http://tutuge.me/) | 65 | - [庞海礁的个人空间 ](http://www.olinone.com/) | 66 | - [Casa Taloyum](http://casatwy.com/) | 67 | - [Kenshin Cui's Blog](http://www.cnblogs.com/kenshincui/) | 68 | - [技术哥的博客](http://suenblog.duapp.com/) | 69 | - [老谭笔记](http://www.tanhao.me/) | 70 | - [coderyi](http://www.coderyi.com/)| 71 | - [雷纯锋的技术博客](http://blog.leichunfeng.com) | 72 | - [iOS技术周报](http://weekly.ios-wiki.com) 73 | 74 | 75 | ## 原文博客 76 | --- 77 | - [holko](http://holko.pl/archive) 78 | - [krakendev](http://krakendev.io) 79 | 80 | ## 工具 81 | --- 82 | 83 | -(oc代码转swift工具)[https://objectivec2swift.com/#/converter/code] 84 | 85 | -------------------------------------------------------------------------------- /res/1418798425343723.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolnameismy/ios-tips/e2b79e6bc648ff8b16b54cbd303132dbdb242602/res/1418798425343723.png -------------------------------------------------------------------------------- /res/1418798425648696.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolnameismy/ios-tips/e2b79e6bc648ff8b16b54cbd303132dbdb242602/res/1418798425648696.png -------------------------------------------------------------------------------- /res/4F9EFDD7-E466-4BE3-8A50-DDC42C91E7E7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolnameismy/ios-tips/e2b79e6bc648ff8b16b54cbd303132dbdb242602/res/4F9EFDD7-E466-4BE3-8A50-DDC42C91E7E7.png --------------------------------------------------------------------------------