常用代码片段备忘

记录一些实用的代码片段

[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
arc4random() % 10000

设计模式

协议

检测协议的实现者是否实现遵循了某个协议方法

1
2
3
4
5
6
7
8
9
10

// 如果设置了 init View,则将 init View 设置到中间
if (self.delegate?.respondsToSelector("initialViewIndexForHorizontalScroller") != false)
{
//println(self.delegate?.respondsToSelector("initialViewIndexForHorizontalScroller"))

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{

//ask the delegate how many view he wants present inside the horizontal scroller
func numberOfViewsForHorizontalScroller(scroller:HorizontalScroller)->NSInteger
//ask the delegate to reuturn the view that should appear at <index>
func horizontalScroller(scroller:HorizontalScroller,viewAtIndex:Int)->UIView
//inform the delegate what the view at <index> has been clicked
func horizontalScroller(scroller:HorizontalScroller,clickedViewIndex:Int)


// ask the delegate for the index of the inital view to display.this method is optional
// and default to 0 if it's not implemented by the delegate
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 progress: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.backgroundColor = UIColor(red: 0.4812, green: 0.0477, 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")
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
}
}

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()
// Do any additional setup after loading the view, typically from a nib.
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()
// Dispose of any resources that can be recreated.
}
}

图片过渡效果和组合动画

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()
// Do any additional setup after loading the view, typically from a nib.

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")!
//self.imageLayer.contents = image2.CGImage

/* 2015-08-03 20:57:53

这段动画只是提交了上去,并没有修改 CALayer 的内容。
提交完成后会立刻恢复动画之前的状态,所有需要动画完成后手动修改CALayer 值
*/

//图片动画
var contentsAnimation:CABasicAnimation = CABasicAnimation(keyPath: "contents")
contentsAnimation.fromValue = self.imageLayer.contents
contentsAnimation.toValue = image2.CGImage
contentsAnimation.duration = 3

//bounds 动画
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(contentsAnimation, forKey: nil)

//组合动画
self.imageLayer.addAnimation(groupAnimation, forKey: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

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()
// Do any additional setup after loading the view, typically from a nib.

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

//给图片提供遮罩的 layer
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()
// Dispose of any resources that can be recreated.
}
}

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) {
// Drawing code
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) {
// Drawing code
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

}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code

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)

//恢复之前的 context,避免处理单个图片时影响到整个 context 的状态。
CGContextRestoreGState(context)

//如果没有恢复之前的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
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
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];
// we can't use an enumerator here, because we don't want to enumerate over ALL of the UIScrollView subviews.
// we want to enumerate only the subviews that we added
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()

//呈现 album 数据

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,
};