目錄ios
第一部分 iOS6新內容git
第二部分 從天天工具中獲取更多(介紹平常使用控件和框架的潛力)github
第三部分 完成任務的正確工具(介紹不是那麼經常使用的控件和框架)設計模式
第四部分 發揮到極限(深刻理解iOS)app
前言框架
本書不適合沒有iOS基礎和實踐經驗的讀者,更適合那些已經開發了一個app有必定經驗的讀者。着重點更多在於爲何這麼作,而不是如何實現。更多關注設計模式,如何設計,編寫ios app,選擇合適的工具來解決平常開發遇到的問題。ide
源碼地址工具
The Code | iOS 7 Programming: Pushing the limits
http://iosptl.com/code/動畫
iosptl/ios7ptl · GitHub
https://github.com/iosptl/ios7ptlatom
iOS 繪圖代碼
#import "LineView.h" @implementation LineView - (void)drawRect:(CGRect)rect { CGContextRef context=UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor); CGContextSetLineWidth(context, 3.0); // Draw 3pt horizontal line from {10,100} to {200,100} CGContextMoveToPoint(context, 10.0, 100.0); CGContextAddLineToPoint(context, 200.0, 100.0); CGContextStrokePath(context); // Draw 3pt horizontal line from {10,105.5} to {200,105.5} CGContextMoveToPoint(context, 10.0, 105.5); CGContextAddLineToPoint(context, 200.0, 105.5); CGContextStrokePath(context); } @end
vc中調用
LineView *lineView=[[LineView alloc]initWithFrame:self.view.bounds]; lineView.backgroundColor=[UIColor whiteColor]; [self.view addSubview:lineView];
#import "FlowerView.h" @implementation FlowerView - (void)drawRect:(CGRect)rect { CGSize size = self.bounds.size; CGFloat margin = 10; CGFloat radius = rint(MIN(size.height - margin, size.width - margin) / 4); CGFloat xOffset, yOffset; CGFloat offset = rint((size.height - size.width) / 2); if (offset > 0) { xOffset = rint(margin / 2); yOffset = offset; } else { xOffset = -offset; yOffset = rint(margin / 2); } [[UIColor redColor] setFill]; UIBezierPath *path = [UIBezierPath bezierPath]; [path addArcWithCenter:CGPointMake(radius * 2 + xOffset,15) radius:radius startAngle:-M_PI endAngle:0 clockwise:YES]; [path addArcWithCenter:CGPointMake(radius * 3 + xOffset, radius * 2 + yOffset) radius:radius startAngle:-M_PI_2 endAngle:M_PI_2 clockwise:YES]; [path addArcWithCenter:CGPointMake(radius*2+xOffset, radius*3+yOffset) radius:radius startAngle:0 endAngle:M_PI clockwise:YES]; [path addArcWithCenter:CGPointMake(radius*2+xOffset, radius*3+yOffset) radius:radius startAngle:0 endAngle:M_PI clockwise:YES]; [path addArcWithCenter:CGPointMake(radius + xOffset, radius * 2 + yOffset) radius:radius startAngle:M_PI_2 endAngle:-M_PI_2 clockwise:YES]; [path closePath]; [path fill]; }
在vc中調用
FlowerView *flowerView=[[FlowerView alloc]initWithFrame:self.view.bounds]; [self.view addSubview:flowerView];
效果圖以下所示
#import "GraphView.h" @implementation GraphView { dispatch_source_t _timer; } const CGFloat kXScale = 5.0; const CGFloat kYScale = 100.0; static inline CGAffineTransform CGAffineTransformMakeScaleTranslate(CGFloat sx, CGFloat sy, CGFloat dx, CGFloat dy) { return CGAffineTransformMake(sx, 0.f, 0.f, sy, dx, dy); } - (void)awakeFromNib { [super awakeFromNib]; [self setContentMode:UIViewContentModeRight]; _values = [NSMutableArray array]; __weak id weakSelf = self; //設定繪圖的間隔時間 double delayInSeconds = 0.25; _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); dispatch_source_set_timer( _timer, dispatch_walltime(NULL, 0), (unsigned)(delayInSeconds * NSEC_PER_SEC), 0); dispatch_source_set_event_handler(_timer, ^{ [weakSelf updateValues]; }); dispatch_resume(_timer); } - (void)updateValues { double nextValue = sin(CFAbsoluteTimeGetCurrent()) + ((double)rand()/(double)RAND_MAX); [self.values addObject: [NSNumber numberWithDouble:nextValue]]; CGSize size = self.bounds.size; CGFloat maxDimension = MAX(size.height, size.width); NSUInteger maxValues = (NSUInteger)floorl(maxDimension / kXScale); if ([self.values count] > maxValues) { [self.values removeObjectsInRange: NSMakeRange(0, [self.values count] - maxValues)]; } [self setNeedsDisplay]; } - (void)drawRect:(CGRect)rect { if ([self.values count] == 0) { return; } CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(ctx, [[UIColor redColor] CGColor]); CGContextSetLineJoin(ctx, kCGLineJoinRound); CGContextSetLineWidth(ctx, 5); CGMutablePathRef path = CGPathCreateMutable(); CGFloat yOffset = self.bounds.size.height / 2; CGAffineTransform transform = CGAffineTransformMakeScaleTranslate(kXScale, kYScale, 0, yOffset); CGFloat y = [[self.values objectAtIndex:0] floatValue]; CGPathMoveToPoint(path, &transform, 0, y); for (NSUInteger x = 1; x < [self.values count]; ++x) { y = [[self.values objectAtIndex:x] floatValue]; CGPathAddLineToPoint(path, &transform, x, y); } CGContextAddPath(ctx, path); CGPathRelease(path); CGContextStrokePath(ctx); } @end
在vc中調用
須要建立一個xib文件和一了類,而後將xib的class設置爲GraphView
NSArray * nib = [[NSBundle mainBundle]loadNibNamed:@"GraphView" owner:self options:nil] ; GraphView *graphView= [nib lastObject]; [self.view addSubview:graphView];
-(UIImage *)reverseImageForText:(NSString *)text{ const size_t kImageWidth=200; const size_t kImageHeight=200; CGImageRef textImage=NULL; UIFont *font=[UIFont boldSystemFontOfSize:13.0]; UIGraphicsBeginImageContext(CGSizeMake(kImageWidth, kImageHeight)); [[UIColor redColor]set]; [text drawInRect:CGRectMake(0, 0, kImageWidth, kImageHeight) withAttributes:@{NSFontAttributeName:font}]; textImage=UIGraphicsGetImageFromCurrentImageContext().CGImage; UIGraphicsEndImageContext(); return [UIImage imageWithCGImage:textImage scale:1.0 orientation:UIImageOrientationDownMirrored]; }
調用
UIImageView *imageView=[[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)]; imageView.image= [self reverseImageForText:@"Hello World!"]; imageView.backgroundColor=[UIColor lightGrayColor]; [self.view addSubview:imageView];
iOS 須要從新繪製整個視圖
setNeedsDisplay,若是隻想繪製部分視圖,能夠使用CALayer
CGLayer高效的一種繪圖
#import "LayerView.h" @implementation LayerView // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { static CGLayerRef sTextLayer = NULL; CGContextRef ctx = UIGraphicsGetCurrentContext(); if (sTextLayer == NULL) { CGRect textBounds = CGRectMake(0, 0, 200, 100); sTextLayer = CGLayerCreateWithContext(ctx, textBounds.size, NULL); CGContextRef textCtx = CGLayerGetContext(sTextLayer); CGContextSetRGBFillColor (textCtx, 1.0, 0.0, 0.0, 1); UIGraphicsPushContext(textCtx); UIFont *font = [UIFont systemFontOfSize:13.0]; [@"Pushing The Limits" drawInRect:textBounds withFont:font]; UIGraphicsPopContext(); } CGContextTranslateCTM(ctx, self.bounds.size.width / 2, self.bounds.size.height / 2); for (NSUInteger i = 0; i < 10; ++i) { CGContextRotateCTM(ctx, 2 * M_PI / 10); CGContextDrawLayerAtPoint(ctx, CGPointZero, sTextLayer); } } @end
調用代碼
LayerView *layerView=[[LayerView alloc]initWithFrame:self.view.bounds]; layerView.backgroundColor=[UIColor whiteColor]; [self.view addSubview:layerView];
效果圖
#import "ViewController.h" @interface ViewController () @property (nonatomic,strong) UIView *circleView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.circleView = [[UIView alloc] initWithFrame: CGRectMake(100, 100, 20, 20)]; self.circleView.center = CGPointMake(100, 20); self.circleView.backgroundColor=[UIColor redColor]; [[self view] addSubview:self.circleView]; UITapGestureRecognizer *g; g = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dropAnimate)]; [[self view] addGestureRecognizer:g]; } - (void)dropAnimate { [UIView animateWithDuration:3 animations:^{ self.circleView.center = CGPointMake(100, 300); }]; }
UIView animation只提供基本的動畫功能,不支持3d,更多效果須要使用core animation的CALayer
CALayer只負責繪圖,不處理用戶事件
tableview的內容
下拉刷新和上拉加載更多
下拉刷新能夠用UIRefreshControl
上拉加載更多能夠本身封裝一個tableview的superClass在最後加上section,顯示加載更多的內容
鍵盤遮擋的一種解決方法
經過接收鍵盤出現的通知,將tableview的高度減去鍵盤的高度。接收鍵盤消失的通知,加上鍵盤的高度,這樣就OK。