Liang's Blog

Dont worry,be happy.

Draw Circle

| Comments

核心英雄

1
PopAnimation CAShapeLayer kPOPShapeLayerStrokeEnd

使用CAShapeLayer与UIBezierPath画出想要的图形(http://blog.csdn.net/volcan1987/article/details/9969455)

1
2
3
4
1、新建UIBezierPath对象bezierPath
2、新建CAShapeLayer对象caShapeLayer
3、将bezierPath的CGPath赋值给caShapeLayer的path,即caShapeLayer.path = bezierPath.CGPath
4、把caShapeLayer添加到某个显示该图形的layer中

下边代码完成了绘制一个圆圈,使用动画的方式呈现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    self.circle = [CAShapeLayer layer];
    self.circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(location.x - radius,
                                                                          location.y - radius,
                                                                          radius*2,
                                                                          radius*2)
                                                  cornerRadius:radius].CGPath;
    
    // Configure the apperence of the circle
    self.circle.fillColor = [UIColor clearColor].CGColor;
    self.circle.strokeColor = [UIColor whiteColor].CGColor;
    self.circle.lineWidth = 2;
    self.circle.strokeEnd = 0.0;
    
    // Add to parent layer
    [self.layer addSublayer:self.circle];
    
    POPBasicAnimation *draw = [POPBasicAnimation animationWithPropertyNamed:kPOPShapeLayerStrokeEnd];
    draw.fromValue = @(0.0);
    draw.toValue = @(1.0);
    draw.duration = 0.8;
    draw.delegate = self;
    [draw setValue:@"draw" forKey:@"animName"];
    draw.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.circle pop_addAnimation:draw forKey:@"draw"];

代码来源 https://github.com/iBaro/PopPlayground

原创作品,转载请注明出处,谢谢。

POPSpringAnimation Demo

| Comments

铺界面的时候加上这个动画效果,所有的视图会依次呈现

1
2
3
4
5
6
7
8
9
//todo 这儿是要创建的一些视图,比如10个view

//ADD APPEAR ANIMATION
POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPViewAlpha];
anim.springBounciness = 8;//弹跳性能,0-20越大弹跳效果越好
anim.springSpeed = 4;//
anim.toValue = @(1.0);
anim.beginTime = CACurrentMediaTime()+0.1*tag;//出现时间
[view pop_addAnimation:anim forKey:@"appear"];

BoundsAnimation,下面的动画是把一个圆形变成了椭圆形

1
2
3
4
5
6
7
8
9
10
11
POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBounds];
CGFloat amount = 80.0;
if (CGRectGetHeight(view.frame) == CGRectGetWidth(view.frame)) {
    anim.toValue = [NSValue valueWithCGRect:CGRectInset(view.frame, -amount, 0)];
    anim.springBounciness = 18;
} else {
    anim.toValue = [NSValue valueWithCGRect:CGRectMake(720, 180, 80, 80)];
}

anim.springSpeed = 10;
[view.layer pop_addAnimation:anim forKey:@"popBounds"];

XRotationAnimation 记录下这个是想为写硬币动画的同学有一些帮助

1
2
3
4
5
6
POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotationY];
    anim.duration = 1.0;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    view.layer.anchorPoint = CGPointMake(0.5, 0.5);
    anim.toValue = @(2*M_PI);
    [view.layer pop_addAnimation:anim forKey:@"popRotationY"];

PS:

anchorPoint,不得不说这篇文章介绍的太详细啦:http://www.tuicool.com/articles/MvI7fu3

原创作品,转载请注明出处,谢谢。

Pop Demo

| Comments

利用弹跳动画写一个视图拉伸

1.创建一个视图,并为视图添加拖拽手势

1
2
3
4
5
6
self.testView = [[UIView alloc] initWithFrame:CGRectMake(0, 100, 100, 100)];
    self.testView.backgroundColor = [UIColor redColor];
    [self.view addSubview:self.testView];

UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panHandler:)];
[self.view addGestureRecognizer:panGestureRecognizer];

2.响应手势做动画变换

1
2
3
4
5
6
7
8
9
10
11
12
13
POPSpringAnimation *positionAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPosition];
    positionAnimation.velocity = [NSValue valueWithCGPoint:velocity];//速度
    positionAnimation.dynamicsTension = 5;//延伸
    positionAnimation.dynamicsFriction = 15.0f;//摩擦
    positionAnimation.springBounciness = 20.0f;//弹跳
  [self.testView.layer pop_addAnimation:positionAnimation forKey:@"positionAnimation"];//位置变换


      POPSpringAnimation *sizeAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerSize];
    sizeAnimation.velocity = [NSValue valueWithCGPoint:velocity];
    sizeAnimation.springBounciness = 1.0f;
    sizeAnimation.dynamicsFriction = 1.0f;
    [self.testView.layer pop_addAnimation:sizeAnimation forKey:@"sizeAnimation"]; //大小变换

可以看到两个pop弹跳动画,主要是名字不同kPOPLayerPosition ,kPOPLayerSize。

原创作品,转载请注明出处,谢谢。

Pop Introduce

| Comments

Pop是一个适用于iOS和OS X平台的可扩展动画引擎,由facebook开源的。

主要分为四个功能。 1.基本的静态动画 2.spring动画 3.decay动画 4.自定义动画

基本动画

1
2
3
4
5
POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPViewAlpha]; 
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; //过渡动画直接使用系统的参数
anim.fromValue = @(0.0); 
anim.toValue = @(1.0); 
[view pop_addAnimation:anim forKey:@"slide"]; 

spring

1
2
3
POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBounds]; 
anim.toValue = [NSValue valueWithCGRec t:CGRectMake(0, 0, 400, 400)]; 
[layer pop_addAnimation:anim forKey:@"size"]; 

decay

1
2
3
POPDecayAnimation *anim = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPositionX]; 
anim.velocity = @(1000.); 
[layer pop_addAnimation:anim forKey:@"slide"]; 

原文链接http://www.cocoachina.com/applenews/devnews/2014/0429/8265.html

百度移动统计

| Comments

进行用户分析,在app发布以后也比较关键。百度移动统计帮我们做了大部分的工作,我们需要把百度移动统计加入到工程中来。

1
2
3
4
5
6
7
8
9
1.首先下载百度移动统计SDK。我集成的时候下载的是3.22版本。sdk目录如下
 
2. 在ios_api/Release-iphonesimulator中存在测试用的.a文件和.h文件,上篇博客中提到的集成静态库方式会很好的完成这个工作。
3.TouchJSON第三方框架是集成所需要的,但是采用了非arc的方式,现在建立的工程默认会是arc的,大家可以添加非arc标识 -fnobjc-arc,还有一种比较不错的方式利用cocopods方式自己下载一个,下载下来的默认就是arc的。

platform :ios, '7.0'
pod 'TouchJSON'
4.在ios_demo文件夹下打开demo。

1
2
3
4
5
6
7
8
BaiduMobStat* statTracker = [BaiduMobStat defaultStat];
statTracker.enableExceptionLog = NO;
statTracker.logStrategy = BaiduMobStatLogStrategyCustom;
statTracker.logSendInterval = 1;
statTracker.logSendWifiOnly = YES;
statTracker.sessionResumeInterval = 1;
statTracker.enableDebugOn = YES;//这句代码是调试必须要用到的,如果是打包,就去掉。
[statTracker startWithAppId:@"bcab3780c3"];

统计页面

1
2
3
4
5
- (void)viewDidAppear:(BOOL)animated{
    NSString *className = [[self class] description];
    NSLog(@"%s,%@", __FUNCTION__,className);
    [[BaiduMobStat defaultStat] pageviewStartWithName:className];
}
1
2
3
4
5
- (void)viewDidDisappear:(BOOL)animated{
    NSString *className = [[self class] description];
    NSLog(@"%s,%@", __FUNCTION__,className);
    [[BaiduMobStat defaultStat] pageviewEndWithName:className];
}

原创作品,转载请注明出处,谢谢。

添加静态库

| Comments

开发中免不了会添加一些静态库。这里分享一下添加步骤

1
2
3
4
5
6
1.加入一個新的Header Search Path。此步骤意在添加静态库的.h文件,比如该文件放在你工程的根目录下的include文件夹下。
targets中选择工程,搜索header search,然后添加一个新的search path。输入$SOURCE_ROOT/include

2.在build phases中的Link Binary With Libraries选项下边添加.a依赖。

3.在buldsettings的other link flags 下添加-ObjC标记。這個連結會試著有效率的引入需要的程式碼,有時可以排除static library程式碼。有了這個標誌,所有Objective-C class和library中的類別都可以正確加載。

原文链接:http://www.raywenderlich.com/zh-hans/73864/%E5%BB%BA%E7%AB%8B-ios-%E9%9D%9C%E6%85%8B%E5%87%BD%E5%BC%8F%E5%BA%AB

简单的json Model映射工具

| Comments

平时做开发经常用到json数据,这时候往往需要把json转换成程序内部的model方便做进一步的处理。推荐一款第三方工具Mantle。 基本实现步骤

1
2
3
4
5
6
7
1.下载 https://github.com/Mantle/Mantle

2. 创建一个Model 类 ,继承自MTLModel

3. 实现映射协议 MTLJSONSerializing。协议里有一个require方法 JSONKeyPathsByPropertyKey

4. 对于一些需要特殊处理的需要实现自适应的属性转换方法,该方法对于命名有一定要求,属性命+JSONTransformer

举例

json原型如下

1
2
3
4
dic {
    id = 10;
    name = xiangrikui;
}

model.h

1
2
3
4
5
6
7
#import "MTLModel.h"
#import <Mantle/MTLJSONAdapter.h>

@interface Picture : MTLModel<MTLJSONSerializing>
@property (nonatomic,copy) NSString *id;
@property (nonatomic,copy) NSString *picName;
@end

.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#import "Picture.h"
#import <Mantle/MTLValueTransformer.h>

@implementation Picture
+ (NSDictionary *)JSONKeyPathsByPropertyKey{
    return @{
             @"id":@"id",
             @"picName":@"name"
             };
}

+ (NSValueTransformer *)picNameJSONTransformer {
    return [MTLValueTransformer reversibleTransformerWithForwardBlock:^id(NSString *name) {
        return [name stringByAppendingString:@"_xx"];
    } reverseBlock:^id(NSString *name) {
        return [name substringToIndex:name.length-4];
    }];
}
@end

vc里的调用方式

1
Picture *picture = [MTLJSONAdapter modelOfClass:[Picture class] fromJSONDictionary:dic error:nil];

原创作品,转载请注明出处,谢谢。

RAC

| Comments

核心英雄

1
RAC RACSignal 

样板代码

1
2
3
4
5
6
7
RAC(self.clickbutton, enabled) = [RACSignal combineLatest:@[
                                                                self.username.rac_textSignal,
                                                                self.p1.rac_textSignal,
                                                                self.p2.rac_textSignal
                                                                ] reduce:^id(NSString *name, NSString *p1, NSString *p2){
                                                                    return @(name.length >0 && p1.length>0 && p1 && [p1 isEqualToString:p2]);
                                                                }];

代码用来做表单验证,只有名字长度大于0,并且两次输入密码一致,且长度大于0时才可以点击。

对概念通俗的解释:

1
2
3
ReactiveCocoa是github去年开源的一个项目,是在iOS平台上对FRP的实现。FRP的核心是信号,信号在ReactiveCocoa(以下简称RAC)中是通过RACSignal来表示的,信号是数据流,可以被绑定和传递。

可以把信号想象成水龙头,只不过里面不是水,而是玻璃球(value),直径跟水管的内径一样,这样就能保证玻璃球是依次排列,不会出现并排的情况(数据都是线性处理的,不会出现并发情况)。水龙头的开关默认是关的,除非有了接收方(subscriber),才会打开。这样只要有新的玻璃球进来,就会自动传送给接收方。可以在水龙头上加一个过滤嘴(filter),不符合的不让通过,也可以加一个改动装置,把球改变成符合自己的需求(map)。也可以把多个水龙头合并成一个新的水龙头(combineLatest:reduce:),这样只要其中的一个水龙头有玻璃球出来,这个新合并的水龙头就会得到这个球。

参考文章:http://blog.leezhong.com/ios/2013/06/19/frp-reactivecocoa.html

享元模式

| Comments

享元模式

1
享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。

两个核心英雄

1
享元 享元工厂

在提到享元模式通常都会提到一个围棋游戏,因为一个围棋里边有300多棋子,如果每个棋子都采用一个新对象会非常占用内存,解决方法就是利用享元模式,提取内部共有属性白色/黑色。外部属性位置,大小(frame).最终系统管理的棋子对象只有两个。

我在写demo的时候发现如果是把每个棋子都addsubview到self.view上的话,会发现不论获取多少次,最终界面上只有两个棋子。思来想去最终发现采用drawrect的方式,前提是要把frame单独存取出来,比如可以用一个字典NSDictionary解决。

原文链接:http://blog.csdn.net/lovelion/article/details/7667781

Isequal == 区别

| Comments

事情虽小有的人真愿意去做。

1
2
3
4
5
6
7
8
9
10
11
- (BOOL)isEqual:(id)object {  
// By default, if two variables point to the same object in memory, it should always be // equal  
    if (object == self) {  
        return YES;   
    }  
    if (![object isKindOfClass:[MyItem class]]) {   
        return NO;  
    }  
    MyItem *myItem = (MyItem *)object;  
    return [myItem.identifier isEqual:self.identifier];   
}  

上边便是isequal的方法内容,可以看出==判断也包含在其中。

原文链接: http://blog.csdn.net/devday/article/details/7594669