记录一些实用的代码片段
[toc]
常用代码片段备忘 Xcode 读取资源文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - (NSString *)sampleMarkdown { NSString *samplePath = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"markdown" ]; NSError *error = nil ; NSString *sample = [NSString stringWithContentsOfFile:samplePath encoding:NSUTF8StringEncoding error:&error]; if (error != nil ) { NSLog (@"Error: %@" , error); return nil ; } return sample; }
数学运算 随机数
设计模式 协议 检测协议的实现者是否实现遵循了某个协议方法 1 2 3 4 5 6 7 8 9 10 if (self .delegate?.respondsToSelector("initialViewIndexForHorizontalScroller" ) != false ) { var initialView:CGFloat = CGFloat (self .delegate.initialViewIndexForHorizontalScroller!(self )) scroller.setContentOffset(CGPointMake (initialView * (VIEW_DIMENSIONS + (2 * VIEW_PADDING )), 0 ), animated: true ) }
swift 中定义协议 如果协议继承自 Objective-C 的类,那么协议前面需要加上 @objc。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @objc protocol HorizontalScrollerDelegate :NSObjectProtocol { func numberOfViewsForHorizontalScroller (scroller:HorizontalScroller) ->NSInteger func horizontalScroller (scroller:HorizontalScroller,viewAtIndex:Int) ->UIView func horizontalScroller (scroller:HorizontalScroller,clickedViewIndex:Int) optional func initialViewIndexForHorizontalScroller (scroller:HorizontalScroller) ->NSInteger }
界面 圆形图片和气泡对话框 圆形图片 使用 setCornerRadius
设置图片的边角弧度,如果想让图片周围显示一个圆圈线条,可以在图片上面添加一个透明背景的圆圈图片1 2 [[self .cover layer] setMasksToBounds:YES ]; [[self .cover layer] setCornerRadius:[self .cover cw_width]/2 ];
界面跳转 If you’re in a Navigation Controller:
1 2 ViewController *viewController = [[ViewController alloc] init]; [self .navigationController pushViewController:viewController animated:YES ];
or if you just want to present a new view:
1 2 ViewController *viewController = [[ViewController alloc] init]; [self presentViewController:viewController animated:YES completion:nil ];
动画效果 内容来自极客学院 视频
进度条效果 PrgresssView.swift:
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 class PrgresssView : UIView { private var progressLayer:CALayer ! private var progressPersent:CGFloat = 0 private var progerssWidth:CGFloat = 0 override init (frame: CGRect ) { super .init (frame: frame) progressLayer = CALayer () progressLayer.frame = CGRectMake (0 , 0 , 0 , frame.size.height) progressLayer.backgroundColor = UIColor (red: 1.0 , green: 0.8288 , blue: 0.0 , alpha: 1.0 ).CGColor self .layer.addSublayer(progressLayer) progerssWidth = frame.size.width } func setProgressPersent (progress:CGFloat) { progressPersent = progress if (progressPersent <= 0 ) { self .progressLayer.frame = CGRectMake (0 , 0 , 0 , self .frame.size.height) }else if (progressPersent <= 1 ) { self .progressLayer.frame = CGRectMake (0 , 0 , progressPersent*self .progerssWidth, self .frame.size.height) }else { self .progressLayer.frame = CGRectMake (0 , 0 , self .progerssWidth, self .frame.size.height) } } func getProgressPersent () { } required init (coder aDecoder: NSCoder ) { fatalError("init(coder:) has not been implemented" ) } override func drawRect (rect: CGRect) { } }
ViewController.swift:
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 class ViewController : UIViewController { private var layer:CALayer ! private var _processView:PrgresssView = PrgresssView (frame: CGRectMake (0 , 300 , 300 , 10 )) override func viewDidLoad () { super .viewDidLoad() var timer = NSTimer .scheduledTimerWithTimeInterval(1 , target: self , selector: "layerAnimation" , userInfo: nil , repeats: true ) _processView.backgroundColor = UIColor ( red: 0.5723 , green: 0.5723 , blue: 0.5723 , alpha: 0.0 ) _processView.layer.borderWidth = 1 self .view.addSubview(_processView) } func layerAnimation () { _processView.setProgressPersent(CGFloat (arc4random_uniform(100 ))/100 ) } override func didReceiveMemoryWarning () { super .didReceiveMemoryWarning() } }
图片过渡效果和组合动画 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 52 53 54 55 56 57 class ViewController : UIViewController { private var imageLayer:CALayer ! override func viewDidLoad () { super .viewDidLoad() var image1:UIImage = UIImage (named: "1.jpeg" )! self .imageLayer = CALayer () self .imageLayer.frame = CGRectMake (0 , 0 , 510 , 771 ) self .view.layer.addSublayer(self .imageLayer) self .imageLayer.contents = image1.CGImage var timer = NSTimer .scheduledTimerWithTimeInterval(3 , target: self , selector: "layerAnimation" , userInfo: nil , repeats: false ) } func layerAnimation () { var image2:UIImage = UIImage (named: "2.jpeg" )! 这段动画只是提交了上去,并没有修改 CALayer 的内容。 提交完成后会立刻恢复动画之前的状态,所有需要动画完成后手动修改CALayer 值 */ var contentsAnimation:CABasicAnimation = CABasicAnimation (keyPath: "contents" ) contentsAnimation.fromValue = self .imageLayer.contents contentsAnimation.toValue = image2.CGImage contentsAnimation.duration = 3 var boundsAnimation:CABasicAnimation = CABasicAnimation (keyPath: "bounds" ) boundsAnimation.fromValue = NSValue (CGRect : self .imageLayer.bounds) boundsAnimation.toValue = NSValue (CGRect : CGRectMake (0 , 0 , 510 /2 , 771 /2 )) boundsAnimation.duration = 3 var groupAnimation:CAAnimationGroup = CAAnimationGroup () groupAnimation.animations = [contentsAnimation,boundsAnimation] groupAnimation.duration = 3 self .imageLayer.bounds = CGRectMake (0 , 0 , 510 /2 , 771 /2 ) self .imageLayer.contents = image2.CGImage self .imageLayer.addAnimation(groupAnimation, forKey: nil ) } override func didReceiveMemoryWarning () { super .didReceiveMemoryWarning() } }
CALayer 遮罩效果 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 class ViewController : UIViewController { var imageLayer:CALayer ! var maskLayer:CALayer ! var imageContent:UIImage ! var maskContents:UIImage ! override func viewDidLoad () { super .viewDidLoad() self .imageContent=UIImage (named: "1.jpeg" ) self .maskContents = UIImage (named: "3.png" ) self .imageLayer = CALayer () self .imageLayer.frame = CGRectMake (50 , 50 , 200 , 200 ) self .imageLayer.contents = imageContent.CGImage self .view.layer.addSublayer(imageLayer) self .maskLayer = CALayer () self .maskLayer.frame = self .imageLayer.bounds self .maskLayer.contents = self .maskContents.CGImage self .imageLayer.mask = self .maskLayer var timer = NSTimer .scheduledTimerWithTimeInterval(3 , target: self , selector: "maskLayerAnimation" , userInfo: nil , repeats: false ) } func maskLayerAnimation () { self .maskLayer.frame = CGRectMake (50 , 50 , 200 , 200 ) } override func didReceiveMemoryWarning () { super .didReceiveMemoryWarning() } }
Core Graphic 绘图 内容来自极客学院 视频
画线 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 override func drawRect (rect: CGRect) { var context = UIGraphicsGetCurrentContext () CGContextMoveToPoint (context,100 , 100 ) CGContextAddLineToPoint (context,100 , 200 ) CGContextAddLineToPoint (context, 200 , 200 ) CGContextMoveToPoint (context, 100 , 300 ) CGContextAddLineToPoint (context, 100 , 400 ) CGContextAddLineToPoint (context, 200 , 500 ) CGContextSetRGBStrokeColor (context, 1 , 0 , 1 , 1 ) CGContextSetLineWidth (context, 5 ) CGContextStrokePath (context) }
画矩形 1 2 3 4 5 6 7 8 9 10 11 override func drawRect (rect: CGRect) { var context = UIGraphicsGetCurrentContext () CGContextAddRect (context, CGRect (x: 100 , y: 100 , width: 100 , height: 100 )) CGContextSetRGBFillColor (context, 1 , 0 , 0 , 1 ) CGContextFillPath (context) CGContextSetLineWidth (context, 5 ) CGContextSetRGBStrokeColor (context, 0 , 1 , 0 , 1 ) CGContextStrokeRect (context, CGRect (x: 100 , y: 100 , width: 100 , height: 100 )) }
画圆形 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 override func drawRect (rect: CGRect) { var context = UIGraphicsGetCurrentContext () CGContextAddArc (context, 150 , 200 , 100 ,0 , 3.141592653 *2 ,0 ) CGContextSetRGBStrokeColor (context, 1 , 0 , 0 , 1 ) CGContextFillPath (context) CGContextAddArc (context,150 ,200 ,100 ,0 ,3.141592653 *2 ,0 ) CGContextSetLineWidth (context, 10 ) CGContextStrokePath (context) CGContextAddEllipseInRect (context, CGRect (x: 50 , y: 400 , width: 200 , height: 100 )) CGContextStrokePath (context) }
画图片 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 class DrawImage : UIView { var uiImage:CGImageRef ! required init (coder aDecoder: NSCoder ) { super .init (coder: aDecoder) uiImage = UIImage (named: "walle.jpg" )?.CGImage } override func drawRect (rect: CGRect) { var context = UIGraphicsGetCurrentContext () CGContextSaveGState (context) CGContextTranslateCTM (context, 10 , 400 ) CGContextScaleCTM (context, 1 , -1 ) CGContextDrawImage (context, CGRect (x: 0 , y: 0 , width: 200 , height: 200 ), uiImage) CGContextRestoreGState (context) CGContextStrokeRect (context, CGRect (x: 50 , y: 100 , width: 100 , height: 100 )) } }
绘画板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 override func drawRect (rect: CGRect) { var context = UIGraphicsGetCurrentContext () CGContextAddPath (context, path) CGContextStrokePath (context) } var path = CGPathCreateMutable ()override func touchesBegan (touches: Set<NSObject>, withEvent event: UIEvent) { var p = (touches.first as ! UITouch ).locationInView(self ) CGPathMoveToPoint (path, nil , p.x, p.y) } override func touchesMoved (touches: Set<NSObject>, withEvent event: UIEvent) { var p = (touches.first as ! UITouch ).locationInView(self ) CGPathAddLineToPoint (path, nil , p.x, p.y) setNeedsDisplay() }
注册手势点击事件和检测发生点击所对应的视图 1.注册手势检测
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 - (id)initWithFrame:(CGRect )frame { self = [super initWithFrame:frame]; if (self ) { scroller = [[UIScrollView alloc] initWithFrame:CGRectMake (0 , 0 , frame.size.width, frame.size.height)]; scroller.delegate = self ; [self addSubview:scroller]; UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollerTapped:)]; [scroller addGestureRecognizer:tapRecognizer]; } return self ; }
然后在 scrollerTapped 检测哪个 UIView 被选中。 检测完成后设置选中的 UIView 居中,并发送 delegate 消息通知协议实现者哪个视图发生了点击。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 - (void)scrollerTapped:(UITapGestureRecognizer *)gesture { CGPoint location = [gesture locationInView:gesture.view]; for (int index=0 ; index<[self .delegate numberOfViewsForHorizontalScroller:self ]; index++) { UIView *view = scroller.subviews[index]; if (CGRectContainsPoint (view.frame, location)) { [self .delegate horizontalScroller:self clickedViewAtIndex:index]; [scroller setContentOffset:CGPointMake (view.frame.origin.x - self .frame.size.width/2 + view.frame.size.width/2 , 0 ) animated:YES ]; break ; } } }
手撸界面 手撸 UITableView ViewDidLoad:
1 2 3 4 5 6 7 8 9 10 11 12 13 self .view.backgroundColor = UIColor (red: 0.76 , green: 0.81 , blue: 0.87 , alpha: 1 ) currentAlbumIndex = 0 ; allAlbums = LibraryAPI .sharedInstance.getAlbums() dataTable = UITableView (frame: CGRectMake (0 , 120 , self .view.frame.size.width, self .view.frame.size.height-120 ), style:UITableViewStyle .Grouped ) dataTable.delegate=self dataTable.dataSource=self dataTable.backgroundView=nil self .view.addSubview(dataTable)
cellForRowAtIndexPath:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func tableView (tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCellWithIdentifier("cell" ) as ? UITableViewCell if cell == nil { cell = UITableViewCell (style: UITableViewCellStyle .Value1 , reuseIdentifier: "cell" ) } cell?.textLabel!.text = currentAlbumData["titles" ]!.objectAtIndex(indexPath.row) as ? String cell?.detailTextLabel?.text = currentAlbumData["values" ]!.objectAtIndex(indexPath.row) as ? String return cell! }
Objective-C 混合 Swift Objective-C 调用 Swift 在需要调用 Swift 方法的 .h
文件顶部添加 #import 工程名称-Swift.h
,即可在 Objective-C 中使用 Swift 的类
Swift 调用 Objective-C 在桥接文件加入需要调用的 Objective-C 的 .h
文件即可
1 2 3 4 5 6 #ifndef CycleMemory_CycleMemory_Bridging_Header_h #define CycleMemory_CycleMemory_Bridging_Header_h #include "CycleMemoryApi.h" #endif
枚举 1 2 3 4 5 6 typedef NS_ENUM (NSInteger , AFNetworkReachabilityStatus) { AFNetworkReachabilityStatusUnknown = -1 , AFNetworkReachabilityStatusNotReachable = 0 , AFNetworkReachabilityStatusReachableViaWWAN = 1 , AFNetworkReachabilityStatusReachableViaWiFi = 2 , };