IOS代码库
1 /* 九宫格计算 */ 2 int totalCol = 5;//指定总列数 3 4 CGFloat viewW = 50;//subview宽度 5 CGFloat viewH = 50;//subview高度 6 7 CGFloat marginX = (self.view.bounds.size.width-viewW*totalCol)/(totalCol+1);//计算横向空白间隙 8 CGFloat marginY = marginX;//计算纵向空白间隙(和横向一致) 9 10 for (int i = 0; i<self.appList.count; i++) {//遍历plist中的view信息 一次在view中生成appview 11 12 int col = i%totalCol;//计算appview所在的列 13 int row = i/totalCol;//计算appview所在的行 14 15 CGFloat x = col*viewW+(col+1)*marginX;//计算appview的横坐标 16 CGFloat y = row*viewH+(row+1)*marginY;//计算appview的纵坐标 17 18 UIView *appView = [[UIView alloc] initWithFrame:CGRectMake(x, y, viewW, viewH)]; 19 appView.backgroundColor = [UIColor redColor];//设置appview 20 21 [self.view addSubview:appView];//添加到view中 22 } 23 24 /* 懒加载 */ 25 -(NSArray *)appList 26 { 27 if (!appList) { 28 NSString *path = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"plist"]; 29 appList = [NSArray arrayWithContentsOfFile:path];//加载plist方法 30 NSLog(@"%@",appList); 31 } 32 return appList; 33 }
疯狂猜图
1 //刘凡老师的代码 2 #import "LFViewController.h" 3 #import "LFQuestion.h" 4 5 #define kButtonWidth 35.0 6 #define kButtonHeight 35.0 7 #define kButtonMargin 10.0 8 #define kTotalColumns 7 9 10 @interface LFViewController () 11 12 /** 图像按钮视图 */ 13 @property (weak, nonatomic) IBOutlet UIButton *iconView; 14 @property (weak, nonatomic) IBOutlet UILabel *noLabel; 15 @property (weak, nonatomic) IBOutlet UILabel *titleLabel; 16 @property (weak, nonatomic) IBOutlet UIButton *nextButton; 17 @property (weak, nonatomic) IBOutlet UIButton *scoreButton; 18 19 @property (weak, nonatomic) IBOutlet UIView *answerView; 20 @property (weak, nonatomic) IBOutlet UIView *optionView; 21 22 /** 遮罩按钮视图 */ 23 @property (nonatomic, strong) UIButton *cover; 24 25 /** 答案索引 */ 26 @property (nonatomic, assign) int index; 27 /** 答案数组 */ 28 @property (nonatomic, strong) NSArray *questions; 29 30 @end 31 32 @implementation LFViewController 33 34 - (NSArray *)questions 35 { 36 if (!_questions) { 37 _questions = [LFQuestion questions]; 38 } 39 40 return _questions; 41 } 42 43 - (UIButton *)cover 44 { 45 if (!_cover) { 46 _cover = [[UIButton alloc] init]; 47 _cover.frame = self.view.bounds; 48 _cover.backgroundColor = [UIColor blackColor]; 49 _cover.alpha = 0.0; 50 51 [self.view addSubview:_cover]; 52 53 [_cover addTarget:self action:@selector(bigImage) forControlEvents:UIControlEventTouchUpInside]; 54 } 55 return _cover; 56 } 57 58 /** 修改状态栏样式 */ 59 - (UIStatusBarStyle)preferredStatusBarStyle 60 { 61 return UIStatusBarStyleLightContent; 62 } 63 64 - (void)viewDidLoad 65 { 66 self.index = -1; 67 68 [self nextQuestion]; 69 } 70 71 /** 设置分数 */ 72 - (void)addScore:(int)score 73 { 74 int currentScore = [self.scoreButton.currentTitle intValue]; 75 currentScore += score; 76 [self.scoreButton setTitle:[NSString stringWithFormat:@"%d", currentScore] forState:UIControlStateNormal]; 77 } 78 79 /** 提示按钮 */ 80 - (IBAction)tips 81 { 82 // 清空答案区所有按钮文字 83 for (UIButton *btn in self.answerView.subviews) { 84 [self answerClick:btn]; 85 } 86 87 // 设置第一个答案按钮的文字 88 LFQuestion *q = self.questions[self.index]; 89 NSString *first = [q.answer substringToIndex:1]; 90 91 for (UIButton *btn in self.optionView.subviews) { 92 if ([btn.currentTitle isEqualToString:first]) { 93 [self optionClick:btn]; 94 95 [self addScore:-1000]; 96 break; 97 } 98 } 99 } 100 101 /** 下一题 */ 102 - (IBAction)nextQuestion 103 { 104 // 1. 取出当前答案 105 self.index++; 106 if (self.index == self.questions.count) { 107 NSLog(@"通关!"); 108 return; 109 } 110 111 LFQuestion *question = self.questions[self.index]; 112 113 // 2. 设置界面信息 114 [self setupBasicInfo:question]; 115 116 // 3. 创建答案按钮 117 [self createAnswerButtons:question]; 118 119 // 4. 创建备选按钮 120 [self createOptionButtons:question]; 121 } 122 123 /** 设置基本信息 */ 124 - (void)setupBasicInfo:(LFQuestion *)question 125 { 126 self.noLabel.text = [NSString stringWithFormat:@"%d/%d", self.index + 1, self.questions.count]; 127 self.titleLabel.text = question.title; 128 [self.iconView setImage:question.image forState:UIControlStateNormal]; 129 130 // 如果是最后一题,禁用下一题按钮 131 self.nextButton.enabled = (self.index < (self.questions.count - 1)); 132 } 133 134 /** 创建答案按钮 */ 135 - (void)createAnswerButtons:(LFQuestion *)question 136 { 137 for (UIView *view in self.answerView.subviews) { 138 [view removeFromSuperview]; 139 } 140 141 int length = question.answer.length; 142 143 CGFloat viewW = self.answerView.bounds.size.width; 144 CGFloat startX = (viewW - length * kButtonWidth - (length - 1) * kButtonMargin) * 0.5; 145 146 for (int i = 0; i < question.answer.length; i++) { 147 CGFloat x = startX + i * (kButtonWidth + kButtonMargin); 148 UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(x, 0, kButtonWidth, kButtonHeight)]; 149 [btn setBackgroundImage:[UIImage imageNamed:@"btn_answer"] forState:UIControlStateNormal]; 150 [btn setBackgroundImage:[UIImage imageNamed:@"btn_answer_highlighted"] forState:UIControlStateHighlighted]; 151 [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 152 153 [self.answerView addSubview:btn]; 154 155 [btn addTarget:self action:@selector(answerClick:) forControlEvents:UIControlEventTouchUpInside]; 156 } 157 158 [self createOptionButtons:question]; 159 } 160 161 /** 创建备选按钮 */ 162 - (void)createOptionButtons:(LFQuestion *)question 163 { 164 for (UIView *view in self.optionView.subviews) { 165 [view removeFromSuperview]; 166 } 167 168 int optionLength = question.options.count; 169 170 CGFloat viewW1 = self.optionView.bounds.size.width; 171 CGFloat startX1 = (viewW1 - kTotalColumns * kButtonWidth - (kTotalColumns - 1) * kButtonMargin) * 0.5; 172 for (int i = 0; i < optionLength; i++) { 173 int row = i / kTotalColumns; 174 int col = i % kTotalColumns; 175 176 CGFloat x = startX1 + col * (kButtonWidth + kButtonMargin); 177 CGFloat y = row * (kButtonHeight + kButtonMargin); 178 179 UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, kButtonWidth, kButtonHeight)]; 180 [btn setBackgroundImage:[UIImage imageNamed:@"btn_option"] forState:UIControlStateNormal]; 181 [btn setBackgroundImage:[UIImage imageNamed:@"btn_option_highlighted"] forState:UIControlStateHighlighted]; 182 [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 183 184 [self.optionView addSubview:btn]; 185 [btn setTitle:question.options[i] forState:UIControlStateNormal]; 186 187 // 备选按钮点击事件 188 [btn addTarget:self action:@selector(optionClick:) forControlEvents:UIControlEventTouchUpInside]; 189 } 190 } 191 192 193 /** 点击答案按钮 */ 194 - (void)answerClick:(UIButton *)button 195 { 196 if (button.currentTitle.length == 0) return; 197 198 // 恢复隐藏的备选按钮 199 for (UIButton *btn in self.optionView.subviews) { 200 if ([btn.currentTitle isEqualToString:button.currentTitle] && btn.isHidden == YES) { 201 btn.hidden = NO; 202 203 break; 204 } 205 } 206 207 // 清空按钮文字 208 [button setTitle:nil forState:UIControlStateNormal]; 209 210 // 将答案区的所有按钮设置为黑色 211 for (UIButton *btn in self.answerView.subviews) { 212 [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 213 } 214 } 215 216 /** 点击备选按钮 */ 217 - (void)optionClick:(UIButton *)button 218 { 219 // 1. 隐藏按钮 220 button.hidden = YES; 221 222 // 2. 将按钮文字设置到答案区 223 // 遍历答案区的按钮,找到第一个文字为空的按钮,并设置其文字 224 for (UIButton *btn in self.answerView.subviews) { 225 if (btn.currentTitle.length == 0) { 226 [btn setTitle:button.currentTitle forState:UIControlStateNormal]; 227 break; 228 } 229 } 230 231 // 3. 判断结果 232 // 1> 判断答案是否填满 233 BOOL isFull = YES; 234 NSMutableString *strM = [NSMutableString string]; 235 for (UIButton *btn in self.answerView.subviews) { 236 if (btn.currentTitle.length == 0) { 237 isFull = NO; 238 } else { 239 [strM appendString:btn.currentTitle]; 240 } 241 } 242 243 // 2> 如果答案已经填满 244 if (isFull) { 245 // 比较结果 246 LFQuestion *q = self.questions[self.index]; 247 248 if ([strM isEqualToString:q.answer]) { 249 for (UIButton *btn in self.answerView.subviews) { 250 [btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 251 } 252 253 [self addScore:800]; 254 255 // 0.5秒钟之后显示下一题 256 [self performSelector:@selector(nextQuestion) withObject:nil afterDelay:0.5]; 257 } else { 258 for (UIButton *btn in self.answerView.subviews) { 259 [btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; 260 } 261 } 262 } 263 } 264 265 /** 显示大图 */ 266 - (IBAction)bigImage 267 { 268 if (self.cover.alpha == 0.0) { 269 // 2. 将图像按钮移动到最前面 270 [self.view bringSubviewToFront:self.iconView]; 271 272 // 3. 放大显示图像 273 // 3.1 计算目标位置 274 CGFloat viewW = self.view.bounds.size.width; 275 CGFloat viewH = viewW; 276 CGFloat viewY = (self.view.bounds.size.height - viewH) * 0.5; 277 278 [UIView animateWithDuration:1.0f animations:^{ 279 self.cover.alpha = 0.5; 280 self.iconView.frame = CGRectMake(0, viewY, viewW, viewH); 281 }]; 282 } else { 283 [UIView animateWithDuration:0.5f animations:^{ 284 self.cover.alpha = 0.0; 285 self.iconView.frame = CGRectMake(85, 90, 150, 150); 286 }]; 287 } 288 } 289 290 @end
1 //计算页码 2 -(void)scrollViewDidScroll:(UIScrollView *)scrollView 3 { 4 self.pageControl.currentPage = (scrollView.contentOffset.x + (scrollView.frame.size.width)/2)/( scrollView.frame.size.width); 5 NSLog(@"scrollViewDidScroll"); 6 7 }//(偏移量 + scrollView宽度的一半)/scrollView宽度 理解也很好理解,偏移量达到宽度一半时候 页码为1,达不到页码为0 牛啊!
1 -(void)nextImage 2 { 3 if (4 == self.pageControl.currentPage) { 4 self.pageControl.currentPage = 0; 5 }else{ 6 self.pageControl.currentPage++; 7 } 8 self.scrollView.contentOffset = CGPointMake(self.pageControl.currentPage * self.scrollView.frame.size.width, 0); 9 }//自动切换图片,bug是当前页直接加1,当前页小点移动,然后滚动,滚动过程中,页码又自己设置了,小点回去,又回来,滚动较快,这个bug看不出来 10 11 解决方案: 12 -(void)nextImage 13 { 14 int page = self.pageControl.currentPage; 15 if (4 == page) { 16 page = 0; 17 }else{ 18 page++; 19 } 20 self.scrollView.contentOffset = CGPointMake(page * self.scrollView.frame.size.width, 0); 21 }//获得页码仅用于计算偏移量,不对页码进行修改,页码的计算还是在滚动过程中自己计算
飘雪花刷帧代码
有个疑问这里,定义在方法中的静态变量 自加 循环调用这个方法,刚开始的定义语句为什么不会重新赋值呢?
1 - (void)drawRect:(CGRect)rect 2 { 3 CGContextRef cxt = UIGraphicsGetCurrentContext(); 4 CGContextClearRect(cxt, rect); 5 static float imageY = 1;//为什么这个值不会重新赋值呢?//重复调用这个方法,静态变量不会重复定义,也不会再赋值!//用static修饰局部变量,只创建一次 6 // Drawing code 7 UIImage *image = [UIImage imageNamed:@"snow"]; 8 if (imageY > self.bounds.size.height) { 9 imageY = 1; 10 } 11 [image drawAtPoint:CGPointMake(0, imageY = imageY + 1)]; 12 // [image drawAsPatternInRect:rect]; 13 }
View跟着手指移动代码
1 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 2 { 3 // UITouch *touch = [touches anyObject]; 4 // CGPoint point = [touch locationInView:self.superview]; 5 // NSLog(@"touchesMoved%@",NSStringFromCGPoint(point)); 6 //获取UItouch 7 UITouch *touch = [touches anyObject]; 8 9 //获取到上一次的点 10 CGPoint prePoint = [touch previousLocationInView:self]; 11 //获取当前点 12 CGPoint currentPoint = [touch locationInView:self];//这里用父视图也行,为毛我的不行呢? 13 //计算差值 14 CGFloat moveX = currentPoint.x - prePoint.y; 15 CGFloat moveY = currentPoint.y - prePoint.y; 16 //根据差值,移动View 17 CGPoint temp = self.center; 18 temp.x += moveX; 19 temp.y += moveY; 20 self.center = temp;//代码有问题!!! 21 }
画画板中画线段的方法
1 // 2 // HuaBan.m 3 // 画画板 4 // 5 // Created by dongwenbo on 14-8-7. 6 // Copyright (c) 2014年 dongwenbo. All rights reserved. 7 // 8 9 #import "HuaBan.h" 10 @interface HuaBan () 11 @property(strong,nonatomic)NSMutableArray *totalPoints; 12 @end 13 14 @implementation HuaBan 15 @synthesize totalPoints = _totalPoints; 16 17 -(NSMutableArray *)touchPoints 18 { 19 if (!_totalPoints) { 20 _totalPoints = [NSMutableArray array]; 21 } 22 return _totalPoints; 23 } 24 25 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 26 { 27 UITouch *touch = [touches anyObject]; 28 //存储开始点到小数组中 29 CGPoint startPoint = [touch locationInView:self]; 30 NSMutableArray *subPoints = [NSMutableArray array]; 31 [subPoints addObject:[NSValue valueWithCGPoint:startPoint]]; 32 //把小数组存储到大数组中 33 [self.touchPoints addObject:subPoints]; 34 // [self setNeedsDisplay]; 35 } 36 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 37 { 38 UITouch *touch = [touches anyObject]; 39 //存储正在移动中的点到小数组中 40 CGPoint movingPoint = [touch locationInView:self]; 41 [[self.totalPoints lastObject] addObject:[NSValue valueWithCGPoint:movingPoint]]; 42 [self setNeedsDisplay]; 43 } 44 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 45 { 46 47 } 48 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 49 { 50 51 } 52 53 -(void)drawRect:(CGRect)rect 54 { 55 //拿到图形上下文 56 CGContextRef ctx = UIGraphicsGetCurrentContext(); 57 for (NSMutableArray *currentPoints in self.totalPoints) { 58 for (int index = 0; index < currentPoints.count; index++) { 59 CGPoint point = [[currentPoints objectAtIndex:index] CGPointValue]; 60 if (0 == index) { 61 //绘制起点 62 CGContextMoveToPoint(ctx, point.x, point.y); 63 }else{ 64 //绘制终点 65 CGContextAddLineToPoint(ctx, point.x, point.y); 66 } 67 } 68 } 69 //渲染 70 CGContextStrokePath(ctx); 71 } 72 @end
不用小数组,而用路径
1 // 2 // HuaBan.m 3 // 画画板 4 // 5 // Created by dongwenbo on 14-8-7. 6 // Copyright (c) 2014年 dongwenbo. All rights reserved. 7 // 8 9 #import "HuaBan.h" 10 @interface HuaBan () 11 @property(strong,nonatomic)NSMutableArray *totalPoints; 12 @end 13 14 @implementation HuaBan 15 @synthesize totalPoints = _totalPoints; 16 17 -(void)clearView 18 { 19 //清空数组 20 [self.totalPoints removeAllObjects]; 21 [self setNeedsDisplay]; 22 } 23 -(void)backView 24 { 25 //移除最后一个数组 26 [self.totalPoints removeLastObject]; 27 [self setNeedsDisplay]; 28 } 29 -(void)saveView 30 { 31 /* 32 UIImageWriteToSavedPhotosAlbum(<#UIImage *image#>, <#id completionTarget#>, <#SEL completionSelector#>, <#void *contextInfo#>) 33 */ 34 } 35 36 -(NSMutableArray *)totalPoints 37 { 38 if (!_totalPoints) { 39 _totalPoints = [NSMutableArray array]; 40 } 41 return _totalPoints; 42 } 43 44 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 45 { 46 47 UITouch *touch = [touches anyObject]; 48 //存储开始点到小数组中 49 CGPoint startPoint = [touch locationInView:self]; 50 /* NSMutableArray *subPoints = [NSMutableArray array]; 51 [subPoints addObject:[NSValue valueWithCGPoint:startPoint]]; 52 //把小数组存储到大数组中 53 [self.totalPoints addObject:subPoints]; 54 // [self setNeedsDisplay];*/ 55 56 UIBezierPath *path = [UIBezierPath bezierPath]; 57 [path moveToPoint:startPoint]; 58 [self.totalPoints addObject:path]; 59 } 60 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 61 { 62 63 UITouch *touch = [touches anyObject]; 64 //存储正在移动中的点到小数组中 65 CGPoint movingPoint = [touch locationInView:self]; 66 /* [[self.totalPoints lastObject] addObject:[NSValue valueWithCGPoint:movingPoint]]; 67 [self setNeedsDisplay]; 68 */ 69 UIBezierPath *path = [self.totalPoints lastObject]; 70 [path addLineToPoint:movingPoint]; 71 [self setNeedsDisplay]; 72 } 73 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 74 { 75 76 } 77 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 78 { 79 80 } 81 82 -(void)drawRect:(CGRect)rect 83 { 84 /* 85 //拿到图形上下文 86 CGContextRef ctx = UIGraphicsGetCurrentContext(); 87 for (NSMutableArray *currentPoints in self.totalPoints) { 88 for (int index = 0; index < currentPoints.count; index++) { 89 CGPoint point = [[currentPoints objectAtIndex:index] CGPointValue]; 90 if (0 == index) { 91 //绘制起点 92 CGContextMoveToPoint(ctx, point.x, point.y); 93 }else{ 94 //绘制终点 95 CGContextAddLineToPoint(ctx, point.x, point.y); 96 } 97 } 98 } 99 //渲染 100 CGContextStrokePath(ctx); 101 */ 102 for (UIBezierPath *path in self.totalPoints) { 103 [path stroke]; 104 } 105 } 106 @end
手势解锁实现
1 // 2 // LockView.m 3 // 手势解锁 4 // 5 // Created by dongwenbo on 14-8-7. 6 // Copyright (c) 2014年 dongwenbo. All rights reserved. 7 // 8 9 #import "LockView.h" 10 @interface LockView () 11 //可变数组,存储按钮 12 @property(strong,nonatomic)NSMutableArray *btns; 13 //当前点 14 @property(assign,nonatomic)CGPoint current; 15 16 @end 17 @implementation LockView 18 @synthesize btns = _btns; 19 @synthesize current = _current; 20 //懒加载按钮 21 -(NSMutableArray *)btns 22 { 23 if (!_btns) { 24 _btns = [NSMutableArray array]; 25 } 26 return _btns; 27 } 28 29 - (id)initWithFrame:(CGRect)frame 30 { 31 self = [super initWithFrame:frame]; 32 if (self) { 33 // Initialization code 34 [self setup]; 35 } 36 return self; 37 } 38 39 - (id)initWithCoder:(NSCoder *)aDecoder 40 { 41 if (self = [super initWithCoder:aDecoder]) { 42 [self setup]; 43 } 44 return self; 45 } 46 //创建按钮 并把按钮加到数组中,同时设置按钮的tag 47 -(void)setup 48 { 49 for (int i = 0; i < 9; i++) { 50 UIButton *btn = [UIButton buttonWithType:(UIButtonTypeCustom)]; 51 [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:(UIControlStateNormal)]; 52 [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:(UIControlStateSelected)]; 53 [self addSubview:btn]; 54 // btn.backgroundColor = [UIColor redColor]; 55 btn.userInteractionEnabled = NO; 56 btn.tag = i; 57 } 58 } 59 //获取第一次点击的按钮,并判断点击的点是否在按钮中,是就把按钮选中状态设置为YES 同时判断是不是已经是YES了,同时把按钮加入到数组中 60 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 61 { 62 UITouch *touch = [touches anyObject]; 63 CGPoint startPoint = [touch locationInView:self]; 64 for (UIButton *btn in self.subviews) { 65 if (CGRectContainsPoint(btn.frame, startPoint)&& btn.selected != YES) { 66 btn.selected = YES; 67 [self.btns addObject:btn]; 68 } 69 } 70 } 71 //获取到移动中的点,并把它赋值给属性,刷界面,判断是否在按钮中,是就点亮按钮,并把按钮加入到数组中 72 -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 73 { 74 UITouch *touch = [touches anyObject]; 75 CGPoint movingPoint = [touch locationInView:self]; 76 self.current = movingPoint; 77 [self setNeedsDisplay]; 78 for (UIButton *btn in self.subviews) { 79 if (CGRectContainsPoint(btn.frame, movingPoint)&& btn.selected != YES) { 80 btn.selected = YES; 81 [self.btns addObject:btn]; 82 [self setNeedsDisplay]; 83 } 84 } 85 } 86 //记录密码,清空数组 87 -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 88 { 89 // for (UIButton *btn in self.subviews) { 90 // btn.selected = NO; 91 // } 92 NSMutableString *strM = [NSMutableString string]; 93 for (UIButton *btn in self.btns) { 94 [strM appendFormat:@"%d",btn.tag]; 95 } 96 if ([self.delegate respondsToSelector:@selector(lockViewDidClick:andPwd:)]) { 97 [self.delegate lockViewDidClick:self andPwd:strM]; 98 } 99 NSLog(@"%@",strM); 100 [self.btns makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)]; 101 [self.btns removeAllObjects]; 102 [self setNeedsDisplay]; 103 } 104 //化界面 105 -(void)drawRect:(CGRect)rect 106 { 107 CGContextRef ctx = UIGraphicsGetCurrentContext(); 108 CGContextClearRect(ctx, rect); 109 for (int i = 0; i < self.btns.count; i++) { 110 UIButton *btn = [self.btns objectAtIndex:i]; 111 CGFloat x = btn.center.x; 112 CGFloat y = btn.center.y; 113 if (0 == i) { 114 CGContextMoveToPoint(ctx, x, y); 115 }else{ 116 CGContextAddLineToPoint(ctx, x, y); 117 } 118 } 119 [[UIColor redColor] set]; 120 CGContextSetLineCap(ctx,kCGLineCapRound); 121 CGContextSetLineJoin(ctx, kCGLineCapRound); 122 CGContextSetLineWidth(ctx, 10); 123 CGContextAddLineToPoint(ctx, self.current.x, self.current.y); 124 CGContextStrokePath(ctx); 125 } 126 //计算按钮位置 127 -(void)layoutSubviews 128 { 129 [super layoutSubviews]; 130 for (int i = 0; i < self.subviews.count; i++) { 131 int col = i % 3;//列 132 int row = i / 3;//行 133 CGFloat padding = 16.33; 134 UIButton *btn = [self.subviews objectAtIndex:i]; 135 CGFloat btnW = 74; 136 CGFloat btnH = 74; 137 CGFloat btnX = padding + col * (padding * 2 + btnW); 138 CGFloat btnY = padding + row * (padding * 2 + btnH); 139 btn.frame = CGRectMake(btnX, btnY, btnW, btnH); 140 } 141 } 142 143 @end
代理的搞法
1 // 2 // LockView.h 3 // 手势解锁 4 // 5 // Created by dongwenbo on 14-8-7. 6 // Copyright (c) 2014年 dongwenbo. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 11 @class LockView; 12 @protocol LockViewDelegate <NSObject> 13 14 -(void)lockViewDidClick:(LockView *)lockView andPwd:(NSString *)pwd; 15 16 @end 17 @interface LockView : UIView 18 @property(weak,nonatomic)id<LockViewDelegate> delegate; 19 @end
1 // 2 // ViewController.m 3 // 手势解锁 4 // 5 // Created by dongwenbo on 14-8-7. 6 // Copyright (c) 2014年 dongwenbo. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "LockView.h" 11 @interface ViewController ()<LockViewDelegate> 12 @property (weak, nonatomic) IBOutlet LockView *lockView; 13 14 @end 15 16 @implementation ViewController 17 @synthesize lockView; 18 19 -(void)lockViewDidClick:(LockView *)lockView andPwd:(NSString *)pwd 20 { 21 if ([pwd isEqualToString:@"012345678"]) { 22 NSLog(@"解锁成功!"); 23 } 24 } 25 26 - (void)viewDidLoad 27 { 28 [super viewDidLoad]; 29 // Do any additional setup after loading the view, typically from a nib. 30 self.lockView.delegate = self; 31 } 32 33 - (void)viewDidUnload 34 { 35 [self setLockView:nil]; 36 [super viewDidUnload]; 37 // Release any retained subviews of the main view. 38 } 39 40 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 41 { 42 return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 43 } 44 45 @end
图标抖动
1 #import "ViewController.h" 2 3 @interface ViewController () 4 @property (strong, nonatomic) IBOutlet UIView *imageView; 5 6 @end 7 8 @implementation ViewController 9 @synthesize imageView; 10 11 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 12 { 13 CAKeyframeAnimation *anima = [CAKeyframeAnimation animation]; 14 anima.keyPath = @"transform.rotation"; 15 anima.values = @[@(0),@(-0.134),@(0),@(0.134),@(0)]; 16 anima.removedOnCompletion = NO; 17 anima.fillMode = kCAFillModeForwards; 18 anima.duration = .3; 19 anima.repeatCount = MAXFLOAT; 20 [self.imageView.layer addAnimation:anima forKey:nil]; 21 } 22 @end
转场动画
1 // 2 // ViewController.m 3 // 转场动画 4 // 5 // Created by dongwenbo on 14-8-8. 6 // Copyright (c) 2014年 dongwenbo. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 11 @interface ViewController () 12 @property (weak, nonatomic) IBOutlet UIImageView *imageView; 13 @property (assign,nonatomic) int index; 14 @property (weak, nonatomic) IBOutlet UIButton *preBtn; 15 @property (weak, nonatomic) IBOutlet UIButton *nextBtn; 16 17 - (IBAction)pre:(id)sender; 18 19 - (IBAction)next:(id)sender; 20 @end 21 22 @implementation ViewController 23 @synthesize imageView; 24 @synthesize index; 25 @synthesize preBtn; 26 @synthesize nextBtn; 27 - (IBAction)pre:(id)sender { 28 index --; 29 self.preBtn.enabled = (index != 1);//根据索引判断按钮可不可用 30 self.nextBtn.enabled = YES;//如果点击了向前的按钮,那么向后的按钮一定可用 31 UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",index]]; 32 self.imageView.image = image; 33 /* The name of the transition. Current legal transition types include 34 * `fade', `moveIn', `push' and `reveal'. Defaults to `fade'. */ 35 CATransition *ca = [CATransition animation]; 36 // ca.type = @"cube"; 37 ca.type = @"rippleEffect"; 38 ca.duration = 2; 39 [self.imageView.layer addAnimation:ca forKey:nil]; 40 } 41 42 - (IBAction)next:(id)sender { 43 index ++; 44 self.nextBtn.enabled = (index != 7);//根据索引判断按钮可不了用 45 self.preBtn.enabled = YES;//如果点击了向后的按钮,那么向前的按钮一定可用 46 UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",index]]; 47 self.imageView.image = image; 48 49 CATransition *ca = [CATransition animation]; 50 ca.type = @"cube"; 51 /* An optional subtype for the transition. E.g. used to specify the 52 * transition direction for motion-based transitions, in which case 53 * the legal values are `fromLeft', `fromRight', `fromTop' and 54 * `fromBottom'. */ 55 ca.subtype = @"fromRight"; 56 ca.startProgress = .3;//动画起点 57 ca.endProgress = .7;//动画结束点 实际上就是把整个动画给截成.3-.7之间了 58 // ca.type = @"rippleEffect"; 59 ca.duration = 1; 60 [self.imageView.layer addAnimation:ca forKey:nil]; 61 } 62 -(void)viewDidLoad 63 { 64 self.index = 1;//初始索引为1 65 self.preBtn.enabled = NO;//默认不可用 66 } 67 68 - (void)viewDidUnload { 69 [self setPreBtn:nil]; 70 [self setNextBtn:nil]; 71 [super viewDidUnload]; 72 } 73 @end
组动画
1 // 2 // ViewController.m 3 // 组动画 4 // 5 // Created by dongwenbo on 14-8-8. 6 // Copyright (c) 2014年 dongwenbo. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 11 @interface ViewController () 12 @property (weak, nonatomic) IBOutlet UIView *iconView; 13 14 @end 15 16 @implementation ViewController 17 @synthesize iconView; 18 19 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 20 { 21 CABasicAnimation *a1 = [CABasicAnimation animation]; 22 a1.keyPath = @"transform.translation.y"; 23 a1.toValue = @(200); 24 25 CABasicAnimation *a2 = [CABasicAnimation animation]; 26 a2.keyPath = @"transform.scale"; 27 a2.toValue = @(0.0); 28 29 CABasicAnimation *a3 = [CABasicAnimation animation]; 30 a3.keyPath = @"transform.rotation"; 31 a3.toValue = @(M_PI_2); 32 33 CAAnimationGroup *groupAnima = [CAAnimationGroup animation]; 34 groupAnima.animations = @[a1,a2,a3]; 35 groupAnima.removedOnCompletion = NO; 36 groupAnima.fillMode = kCAFillModeForwards; 37 groupAnima.duration = 10; 38 [self.iconView.layer addAnimation:groupAnima forKey:nil]; 39 } 40 41 @end
UIView封装动画
1 [UIView transitionWithView:self.iconView duration:2 options:0 animations:^{ 2 [UIView setAnimationTransition:(UIViewAnimationTransitionCurlUp) forView:self.iconView cache:YES]; 3 } completion:^(BOOL finished) { 4 5 }];
线程中通信
1 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 2 { 3 [self performSelectorInBackground:@selector(download) withObject:nil]; 4 } 5 6 -(void)download 7 { 8 NSURL *url = [NSURL URLWithString:@"http://images.apple.com/cn/iphone/home/images/ilife_hero.jpg"]; 9 NSData *data = [NSData dataWithContentsOfURL:url]; 10 UIImage *image = [UIImage imageWithData:data]; 11 //因为 imageView没有加锁,在子线程中访问是不安全的,只能在主线程一个线程中访问 12 // [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO]; 13 [self.imageView performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO]; 14 //self.imageView.image = image; 15 }
GCD 1
1 //获取全局的并发队列 2 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 3 //异步方法 添加队列,任务 4 dispatch_async(queue, ^{ 5 NSLog(@"____1 %@",[NSThread currentThread]); 6 }); 7 dispatch_async(queue, ^{ 8 NSLog(@"____2 %@",[NSThread currentThread]); 9 }); 10 dispatch_async(queue, ^{ 11 NSLog(@"____3 %@",[NSThread currentThread]); 12 });
1 //自己创建串行队列 2 dispatch_queue_t queue = dispatch_queue_create("com.dong.queue", NULL); 3 //异步方法 添加串行队列 任务 4 dispatch_async(queue, ^{ 5 NSLog(@"____1 %@",[NSThread currentThread]); 6 }); 7 dispatch_async(queue, ^{ 8 NSLog(@"____2 %@",[NSThread currentThread]); 9 }); 10 dispatch_async(queue, ^{ 11 NSLog(@"____3 %@",[NSThread currentThread]); 12 });
总结共四种情况
情况说明:
同步:不开线程,在当前线程中执行 异步:开新线程
并发队列:可以并发执行 串行队列:不可以并发,只能一个一个
同步+并发:并发无意义
同步+串行:一个一个
异步+并发:开新线程(N),并发执行
异步+串行:开新线程(1),串行任务在新线程中一个一个执行
同步+串行(主队列):放在主线程队列中挨个执行//可能会造成死锁,在主线程中往主线程队列中添加任务,造成死锁
异步+串行(主队列):放在主线程队列中挨个执行,不开新线程//不会造成死锁
1 /** 2 * 使用dispatch_async异步函数, 在主线程中往主队列中添加任务 3 */ 4 - (void)asyncMainQueue 5 { 6 // 1.获得主队列 7 dispatch_queue_t queue = dispatch_get_main_queue(); 8 9 // 2.添加任务到队列中 执行 10 dispatch_async(queue, ^{ 11 NSLog(@"----下载图片1-----%@", [NSThread currentThread]); 12 }); 13 } 14 15 /** 16 * 使用dispatch_sync同步函数, 在主线程中往主队列中添加任务 : 任务无法往下执行 17 */ 18 - (void)syncMainQueue 19 { 20 // 1.获得主队列 21 dispatch_queue_t queue = dispatch_get_main_queue(); 22 23 // 2.添加任务到队列中 执行 24 dispatch_sync(queue, ^{ 25 NSLog(@"----下载图片1-----%@", [NSThread currentThread]); 26 }); 27 // dispatch_sync(queue, ^{ 28 // NSLog(@"----下载图片2-----%@", [NSThread currentThread]); 29 // }); 30 // dispatch_sync(queue, ^{ 31 // NSLog(@"----下载图片3-----%@", [NSThread currentThread]); 32 // }); 33 34 // 不会开启新的线程, 所有任务在主线程中执行 35 }
使用 异步+并发 下载图片
1 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 2 dispatch_async(queue, ^{ 3 NSLog(@"--download--%@", [NSThread currentThread]); 4 // 下载图片 5 NSURL *url = [NSURL URLWithString:@"http://news.baidu.com/z/resource/r/image/2014-06-22/2a1009253cf9fc7c97893a4f0fe3a7b1.jpg"]; 6 NSData *data = [NSData dataWithContentsOfURL:url]; // 这行会比较耗时 7 UIImage *image = [UIImage imageWithData:data]; 8 9 // 回到主线程显示图片 10 dispatch_async(dispatch_get_main_queue(), ^{ 11 NSLog(@"--imageView--%@", [NSThread currentThread]); 12 self.imageView.image = image; 13 }); 14 });
全局并发队列 |
手动创建串行队列 |
主队列 | |
同步(sync) |
p没有开启新线程
p串行执行任务
|
p没有开启新线程
p串行执行任务
|
p没有开启新线程
p串行执行任务(可能会死锁)
|
异步(async) |
p有开启新线程
p并发执行任务
|
p有开启新线程
p串行执行任务
|
p没有开启新线程
p串行执行任务
|
组的用法
同时下载两个图片 两个都下载完毕后 回到主线程 显示图片
1 // 创建一个组 2 dispatch_group_t group = dispatch_group_create(); 3 4 // 开启一个任务下载图片1 5 __block UIImage *image1 = nil; 6 dispatch_group_async(group, global_queue, ^{ 7 image1 = [self imageWithURL:@"http://news.baidu.com/z/resource/r/image/2014-06-22/2a1009253cf9fc7c97893a4f0fe3a7b1.jpg"]; 8 }); 9 10 // 开启一个任务下载图片2 11 __block UIImage *image2 = nil; 12 dispatch_group_async(group, global_queue, ^{ 13 image2 = [self imageWithURL:@"http://news.baidu.com/z/resource/r/image/2014-06-22/b2a9cfc88b7a56cfa59b8d09208fa1fb.jpg"]; 14 }); 15 16 // 同时执行下载图片1\下载图片2操作 17 18 // 等group中的所有任务都执行完毕, 再回到主线程执行其他操作 19 dispatch_group_notify(group, main_queue, ^{ 20 self.imageView1.image = image1; 21 self.imageView2.image = image2; 22 23 // 合并 24 UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 100), NO, 0.0); 25 [image1 drawInRect:CGRectMake(0, 0, 100, 100)]; 26 [image2 drawInRect:CGRectMake(100, 0, 100, 100)]; 27 self.bigImageView.image = UIGraphicsGetImageFromCurrentImageContext(); 28 // 关闭上下文 29 UIGraphicsEndImageContext(); 30 });
单例模式宏定义(可以判断ARC和非ARC)
1 // ## : 连接字符串和参数 2 #define singleton_h(name) + (instancetype)shared##name; 3 4 #if __has_feature(objc_arc) // ARC 5 6 #define singleton_m(name) \ 7 static id _instance; \ 8 + (id)allocWithZone:(struct _NSZone *)zone \ 9 { \ 10 static dispatch_once_t onceToken; \ 11 dispatch_once(&onceToken, ^{ \ 12 _instance = [super allocWithZone:zone]; \ 13 }); \ 14 return _instance; \ 15 } \ 16 \ 17 + (instancetype)shared##name \ 18 { \ 19 static dispatch_once_t onceToken; \ 20 dispatch_once(&onceToken, ^{ \ 21 _instance = [[self alloc] init]; \ 22 }) 23 return _instance; \ 24 } \ 25 + (id)copyWithZone:(struct _NSZone *)zone \ 26 { \ 27 return _instance; \ 28 } 29 30 #else // 非ARC 31 32 #define singleton_m(name) \ 33 static id _instance; \ 34 + (id)allocWithZone:(struct _NSZone *)zone \ 35 { \ 36 static dispatch_once_t onceToken; \ 37 dispatch_once(&onceToken, ^{ \ 38 _instance = [super allocWithZone:zone]; \ 39 }); \ 40 return _instance; \ 41 } \ 42 \ 43 + (instancetype)shared##name \ 44 { \ 45 static dispatch_once_t onceToken; \ 46 dispatch_once(&onceToken, ^{ \ 47 _instance = [[self alloc] init]; \ 48 }); \ 49 return _instance; \ 50 } \ 51 \ 52 - (oneway void)release \ 53 { \ 54 \ 55 } \ 56 \ 57 - (id)autorelease \ 58 { \ 59 return _instance; \ 60 } \ 61 \ 62 - (id)retain \ 63 { \ 64 return _instance; \ 65 } \ 66 \ 67 - (NSUInteger)retainCount \ 68 { \ 69 return 1; \ 70 } \ 71 \ 72 + (id)copyWithZone:(struct _NSZone *)zone \ 73 { \ 74 return _instance; \ 75 } 76 77 #endif
登陆服务器+解析Json
1 // 2 // ViewController.m 3 // Get请求 4 // 5 // Created by dongwenbo on 14-8-10. 6 // Copyright (c) 2014年 dongwenbo. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "MBProgressHUD/MBProgressHUD+MJ.h" 11 @interface ViewController () 12 @property (weak, nonatomic) IBOutlet UITextField *userName; 13 @property (weak, nonatomic) IBOutlet UITextField *pwd; 14 - (IBAction)login:(id)sender; 15 16 @end 17 18 @implementation ViewController 19 @synthesize userName; 20 @synthesize pwd; 21 22 - (void)viewDidLoad 23 { 24 [super viewDidLoad]; 25 // Do any additional setup after loading the view, typically from a nib. 26 } 27 28 - (void)viewDidUnload 29 { 30 [self setUserName:nil]; 31 [self setPwd:nil]; 32 [super viewDidUnload]; 33 // Release any retained subviews of the main view. 34 } 35 36 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 37 { 38 return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 39 } 40 41 - (IBAction)login:(id)sender { 42 NSString *name = self.userName.text; 43 if (name.length == 0) { 44 [MBProgressHUD showError:@"请输入用户名"]; 45 return; 46 } 47 48 NSString *pwdstr = self.pwd.text; 49 if (pwdstr.length == 0) { 50 [MBProgressHUD showError:@"请输入密码"]; 51 return; 52 } 53 54 [MBProgressHUD showMessage:@"正在登陆。。。"]; 55 56 NSString *urlStr = [NSString stringWithFormat:@"http://192.168.1.100:8080/MJServer/login?username=%@&pwd=%@",name,pwdstr]; 57 NSURL *url = [NSURL URLWithString:urlStr]; 58 59 NSURLRequest *request = [NSURLRequest requestWithURL:url]; 60 // NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:nil]; 61 // [conn start]; 62 // [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 63 NSOperationQueue *queue = [NSOperationQueue mainQueue]; 64 [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *request, NSData *data, NSError *error) {//在子线程中发请求,在主线程中刷新UI 65 NSLog(@"%d",data.length); 66 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableLeaves) error:nil]; 67 NSString *error1 = [dict objectForKey:@"error"]; 68 if(error1){ 69 [MBProgressHUD hideHUD]; 70 [MBProgressHUD showError:error1]; 71 }else 72 { 73 [MBProgressHUD hideHUD]; 74 NSString *success = [dict objectForKey:@"success"]; 75 [MBProgressHUD showSuccess:success]; 76 } 77 NSLog(@"%@",dict); 78 }]; 79 NSLog(@"因为是异步"); 80 } 81 @end
解析XML和JSON
1 DOM 2 -(NSArray *)DOMparseXMLData:(NSData *)data 3 { 4 GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil]; 5 GDataXMLElement *root = doc.rootElement; 6 NSArray *elements = [root elementsForName:@"video"]; 7 NSMutableArray *arrM = [[NSMutableArray alloc] init]; 8 for (GDataXMLElement *ele in elements) { 9 Video *video = [[Video alloc] init]; 10 video.ID = [ele attributeForName:@"id"].stringValue.intValue; 11 video.name = [ele attributeForName:@"name"].stringValue; 12 video.url = [ele attributeForName:@"url"].stringValue; 13 video.length = [ele attributeForName:@"length"].stringValue.intValue; 14 video.image = [ele attributeForName:@"image"].stringValue; 15 [arrM addObject:video]; 16 } 17 return arrM; 18 }
1 JSON 2 -(NSArray *)parseJSONdata:(NSData *)data 3 { 4 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableLeaves) error:nil]; 5 NSArray *array = [dict objectForKey:@"videos"]; 6 NSMutableArray *arrM = [NSMutableArray arrayWithCapacity:array.count]; 7 for (NSDictionary *dict in array) { 8 Video *video = [Video videoWithDict:dict]; 9 [arrM addObject:video]; 10 } 11 self.videos = [arrM mutableCopy]; 12 return self.videos; 13 }
1 SAX代理 2 -(NSArray *)parseXMLData:(NSData *)data 3 { 4 NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; 5 parser.delegate = self; 6 [parser parse]; 7 return self.videos; 8 }