核心動(dòng)畫(四)

關(guān)鍵幀動(dòng)畫實(shí)現(xiàn)圍繞路徑移動(dòng)汽車

如果我們想讓一個(gè)物體沿著一個(gè)軌跡移動(dòng),就需要用到UIBezierPath。使用UIBezierPath的兩個(gè)關(guān)鍵點(diǎn)

  • 數(shù)據(jù)點(diǎn)(起點(diǎn)終點(diǎn))、控制點(diǎn)
  • 為了顯示貝塞爾曲線的路徑,需要用到專門的圖層CAShapeLayer

下面使用UIBezierPath、CAShapeLayer實(shí)現(xiàn)一個(gè)汽車圍繞路徑移動(dòng)的動(dòng)畫

#import "ViewController.h"

@interface ViewController ()
@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self test];
}

- (void)test{
    //1.定義貝塞爾曲線
    UIBezierPath *path = [UIBezierPath bezierPath];
    //使用方法moveToPoint:去設(shè)置初始線段的起點(diǎn)
    [path moveToPoint:CGPointMake(20, 200)];
    //設(shè)置EndPoint & Control Point(終點(diǎn)和控制點(diǎn))
    [path addCurveToPoint:CGPointMake(300, 200) controlPoint1:CGPointMake(100, 100) controlPoint2:CGPointMake(200, 300)];
    
    //2.為了顯示貝塞爾曲線的路徑 ->  CAShapeLayer專門用來顯示UIBezierPath圖層
    //CAShapeLayer 使用shapeLayer 可以更高效的渲染圖形.并且不使用drawRect方法
    CAShapeLayer *shapeLyaer = [CAShapeLayer layer];
    //路徑
    shapeLyaer.path = path.CGPath;
    //填充顏色
    //shapeLyaer.fillColor = [UIColor blueColor].CGColor;
    shapeLyaer.fillColor = nil;
    //線段顏色
    shapeLyaer.strokeColor = [UIColor redColor].CGColor;
    //為子圖層添加貝塞爾曲線圖
    [self.view.layer addSublayer:shapeLyaer];
    
    //3.添加??圖層
    CALayer *carLayer = [CALayer layer];
    carLayer.frame = CGRectMake(15, 200-18, 36, 36);
    //寄宿圖
    carLayer.contents = (id)[UIImage imageNamed:@"car"].CGImage;
    carLayer.anchorPoint = CGPointMake(0.5, 0.8);
    [self.view.layer addSublayer:carLayer];
    
    //4.創(chuàng)建關(guān)鍵幀動(dòng)畫,讓汽車沿著路徑移動(dòng)
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    //路徑
    anim.keyPath = @"position";
    //path
    anim.path = path.CGPath;
    //時(shí)長
    anim.duration = 4.0;
    //rotationMode
    anim.rotationMode = kCAAnimationRotateAuto;
    //為汽車圖層添加動(dòng)畫
    [carLayer addAnimation:anim forKey:nil];
}

@end
汽車移動(dòng)動(dòng)畫

物理引擎的簡單使用

物理引擎是由UIKit提供的,負(fù)責(zé)了動(dòng)畫和交互的體系。UIDynamic引擎是iOS7.o引入的的技術(shù),其目的是解放開發(fā)者,可以遠(yuǎn)離物理公式

UIDynamic物理引擎重要的類

  • 重力行為:UIGravityBehavior
  • 碰撞行為:UICollisionBehavior
  • 捕捉行為:UISnapBehavior
  • 推動(dòng)行為:UIPushBehavior
  • 附著行為:UIAttchmentBehavior
  • 動(dòng)力元素行為:UIDynamicItemBehavior

使用2D物理引擎的兩個(gè)步驟

  • 添加行為,需要綁定view
  • 將行為添加到容器中

下面我們來使用一些常用的物理引擎,代碼如下

#import "ViewController.h"

@interface ViewController ()
@property(nonatomic,strong)UIDynamicAnimator * animator;
@property(nonatomic,strong)UIDynamicAnimator * animator2;
@property(nonatomic,strong)UIAttachmentBehavior * attachmentBehavior;

@property(nonatomic,strong)UIImageView * redView;
@property(nonatomic,strong)UIImageView * greenView;
@property(nonatomic,strong)UIImageView * yellowView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //UI實(shí)現(xiàn)
    self.view.backgroundColor = [UIColor whiteColor];
   
    //紅色球
    _redView =[[UIImageView alloc]initWithFrame:CGRectMake(100, 200, 50, 50)];
    _redView.image = [UIImage imageNamed:@"ball.png"];
    _redView.userInteractionEnabled = YES;
    _redView.backgroundColor =[UIColor redColor];
    _redView.layer.masksToBounds = YES;
    _redView.layer.cornerRadius = 25;
    [self.view addSubview:_redView];
    
    //綠色球
    _greenView =[[UIImageView alloc]initWithFrame:CGRectMake(100, 400, 50, 50)];
    _greenView.backgroundColor =[UIColor greenColor];
    _greenView.image = [UIImage imageNamed:@"ball2.png"];
    _greenView.userInteractionEnabled = YES;
    _greenView.layer.masksToBounds = YES;
    _greenView.layer.cornerRadius = 25;
    [self.view addSubview:_greenView];
    
    //黃色球
    _yellowView =[[UIImageView alloc]initWithFrame:CGRectMake(200, 500, 50, 50)];
    _yellowView.backgroundColor =[UIColor yellowColor];
    _yellowView.image = [UIImage imageNamed:@"ball3.png"];
    _yellowView.userInteractionEnabled = YES;
    _yellowView.layer.masksToBounds = YES;
    _yellowView.layer.cornerRadius = 25;
    [self.view addSubview:_yellowView];
    
    //物理引擎
    [self animator];
    
    //創(chuàng)建自由落體行為-重力,初始化哪幾個(gè)view要接收這樣的重力行為
    UIGravityBehavior *gravity = [[UIGravityBehavior alloc]initWithItems:@[_redView,_yellowView,_greenView]];
    //重力行為有一個(gè)屬性是重力加速度,設(shè)置越大速度增長越快。默認(rèn)是1
    gravity.magnitude = 2;
    //添加到容器
    [_animator addBehavior:gravity];
    
    //碰撞行為
     UICollisionBehavior *collision =[[UICollisionBehavior alloc]initWithItems:@[_redView,_yellowView,_greenView]];
    //設(shè)置邊緣(父View的bounds)
    collision.translatesReferenceBoundsIntoBoundary = YES;
    
    //可以利用貝塞爾曲線限制邊界
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:
                          CGRectMake(0,150, self.view.frame.size.width, self.view.frame.size.width)];
    CAShapeLayer * shapeLayer =[CAShapeLayer layer];
    shapeLayer.path =path.CGPath;
    //畫筆顏色
    shapeLayer.strokeColor =[UIColor redColor].CGColor;
    shapeLayer.lineWidth = 5;
    //填充顏色
    shapeLayer.fillColor = nil;
    [self.view.layer addSublayer:shapeLayer];
    [collision addBoundaryWithIdentifier:@"circle" forPath:path];
    [_animator addBehavior:collision];
    
    //模擬捕捉行為
    //捕捉行為需要在創(chuàng)建時(shí)就給與一個(gè)點(diǎn)
    //捕捉行為有一個(gè)防震系數(shù)屬性,設(shè)置的越大,振幅就越小
    CGPoint point = CGPointMake(10, 400);
    UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:_greenView snapToPoint:point];
    snap.damping = 1;
    [_animator addBehavior:snap];
    
    //其他行為的拓展
    UIDynamicItemBehavior *itemBehavior =[[UIDynamicItemBehavior alloc]initWithItems:@[_redView]];
    /*
     elasticity 彈性系數(shù)
     friction   摩擦系數(shù)
     density    密度
     resistance 抵抗性
     angularResistance 角度阻力
     charge     沖擊
     anchored   錨定
     allowsRotation 允許旋轉(zhuǎn)
     */
    itemBehavior.elasticity =.6;//彈性系數(shù)
    [_animator addBehavior:itemBehavior];
    
    //添加手勢
    UIPanGestureRecognizer *pan =[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAuction:)];
    [_redView addGestureRecognizer:pan];
}

-(void)panAuction:(UIPanGestureRecognizer *)ges{
    if (ges.state == UIGestureRecognizerStateBegan) {
        UIOffset offset = UIOffsetMake(-10, -10);
        /*
         offsetFromCenter:偏離中心幅度
         attachedToAnchor:附加到錨點(diǎn) 手勢點(diǎn)擊的位置
         */
        //UIAttachmentBehavior 附著行為
        _attachmentBehavior =[[UIAttachmentBehavior alloc]initWithItem:_redView offsetFromCenter:offset attachedToAnchor:[ges locationInView:self.view]];
        
        [_animator addBehavior:_attachmentBehavior];
    }else if (ges.state == UIGestureRecognizerStateChanged){
        //設(shè)置錨點(diǎn)
        [_attachmentBehavior setAnchorPoint:[ges locationInView:self.view]];
    }else if (ges.state ==UIGestureRecognizerStateEnded || ges.state == UIGestureRecognizerStateFailed || ges.state == UIGestureRecognizerStateCancelled){
        [_animator removeBehavior:_attachmentBehavior];
    }
}

//懶加載
- (UIDynamicAnimator *)animator
{
    if (!_animator) {
        // 創(chuàng)建一個(gè)物理仿真器,關(guān)聯(lián)到一個(gè)view上
        //容器(里面放一些行為)
        /*
         ReferenceView:關(guān)聯(lián)的view
         */
        _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
    }
    return _animator;
}

@end
引擎效果

足球從上面掉落下來把籃球撞擊上去,同時(shí)我們給_redView足球添加了一個(gè)拖拽手勢,可以把足球拖上去使其掉下來再次撞擊籃球。

下面我們給籃球添加一個(gè)捕捉行為,點(diǎn)擊屏幕隨意更改其位置

- (void)viewDidLoad {
    [super viewDidLoad];
    _animator2 = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 1.獲得手指對應(yīng)的觸摸對象
    UITouch *touch = [touches anyObject];
    
    // 2.獲得觸摸點(diǎn)
    CGPoint point = [touch locationInView:self.view];
    
    // 3.創(chuàng)建捕捉行為
    UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:_yellowView snapToPoint:point];
    
    // 防震系數(shù),damping越大,振幅越小
    snap.damping = 1;
    
    // 4.清空之前的并再次開始
    [_animator2 removeAllBehaviors];
    [_animator2 addBehavior:snap];
}

貝塞爾曲線

貝塞爾曲線(Bézier curve),又稱?茲曲線貝濟(jì)埃曲線,是應(yīng)?于?維圖形應(yīng)用程序的數(shù)學(xué)曲線。一 般的矢量圖形軟件通過它來精確畫出曲線,貝茲曲線由線段與節(jié)點(diǎn)組成,節(jié)點(diǎn)是可拖動(dòng)的支點(diǎn),線段像可伸縮的?筋,我們在繪圖工具上看到的鋼筆工具就是來做這種矢量曲線的。貝塞爾曲線是計(jì)算機(jī)圖形學(xué)中相當(dāng)重要的參數(shù)曲線,在?些比較成熟的位圖軟件中也有貝塞爾曲線工具,如PhotoShop等。

貝塞爾曲線于1962,由法國工程師皮埃爾·貝塞爾(Pierre Bézier)所廣泛發(fā)表,他運(yùn)用?塞爾曲線來為汽?的主體進(jìn)行設(shè)計(jì)。?塞爾曲線最初由Paul de Casteljau于1959年運(yùn)用de Casteljau演算法開發(fā),以穩(wěn)定數(shù)值的方法求出貝茲曲線。

貝塞爾曲線

貝塞爾曲線原理

UIBezierPath屬性與方法
- 初始化方法
  初始化方法,需要用實(shí)例方法添加線條。使用比較多,可以根據(jù)需要任意定制樣式,畫任何我們想畫的圖形。
+ (instancetype)bezierPath;

  返回一個(gè)矩形path
+ (instancetype)bezierPathWithRect:(CGRect)rect;

  返回一個(gè)圓形或者橢圓形path
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;

  返回一個(gè)帶圓角的矩形path,矩形的四個(gè)角都是圓角
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;

 返回一個(gè)帶圓角的矩形path,UIRectCorner 枚舉值可以設(shè)置只繪制某個(gè)圓角
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;

 返回一段圓弧,參數(shù)說明:center:弧線中心點(diǎn)的坐標(biāo)  radius:弧線所在圓的半徑 startAngle:弧線開始的角度值 endAngle:弧線結(jié)束的角度值 clockwise:是否順時(shí)針畫弧線
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;

 用一條 CGpath 初始化
+ (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;

 返回一個(gè)反轉(zhuǎn)當(dāng)前路徑的路徑對象(反方向繪制path)
- (UIBezierPath *)bezierPathByReversingPath API_AVAILABLE(ios(6.0));
屬性
CGPath:將UIBezierPath類轉(zhuǎn)換成CGPath
currentPoint:當(dāng)前path的位置,可以理解為path的終點(diǎn)
lineWidth:線條寬度
lineCapStyle:端點(diǎn)樣式
lineJoinStyle:連接類型
flatness:繪線的精細(xì)程度,默認(rèn)為0.6,數(shù)值越大,需要處理的時(shí)間越長
usesEvenOddFillRule:判斷奇偶數(shù)組的規(guī)則繪制圖像,圖形復(fù)雜時(shí)填充顏色的一種規(guī)則。類似棋盤
miterLimit:最大斜接長度 (只有在使用kCGLineJoinMiter時(shí)才有效,最大限制為10) ,邊角的角度越小,斜接長度就會越大,為了避免斜接長度過長,使用lineLimit屬性限制,如果斜接長度超過miterLimit,邊角就會以KCALineJoinBevel類型來顯示
- setLineDash: count: phase: 為path繪制虛線,dash數(shù)組存放各段虛線的長度,count是數(shù)組元素?cái)?shù)量,phase是起始位置

lineCapStyle - 端點(diǎn)類型
kCGLineCapButt:無端點(diǎn)
kCGLineCapRound:圓形端點(diǎn)
kCGLineCapSquare:方形端點(diǎn)(樣式上和kCGLineCapButt是一樣的,但是比kCGLineCapButt長一點(diǎn))

lineJoinStyle - 交叉點(diǎn)的類型
kCGLineJoinMiter:尖角銜接
kCGLineJoinRound:圓角銜接
kCGLineJoinBevel:斜角銜接
UIBezierPath構(gòu)建Path
 以point點(diǎn)開始作為起點(diǎn),一般用 + (instancetype)bezierPath 創(chuàng)建的貝塞爾曲線,先用該方法標(biāo)注一個(gè)起點(diǎn),再調(diào)用其他的創(chuàng)建線條的方法來繪制曲線
- (void)moveToPoint:(CGPoint)point;

 繪制二次貝塞爾曲線的關(guān)鍵方法,即從path的最后一點(diǎn)開始添加一條線到point點(diǎn)
- (void)addLineToPoint:(CGPoint)point;

 繪制二次貝塞爾曲線的關(guān)鍵方法,和 -moveToPoint: 配合使用。endPoint為終止點(diǎn),controlPoint為控制點(diǎn)
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;

 繪制三次貝塞爾曲線的關(guān)鍵方法,以三個(gè)點(diǎn)畫一段曲線。一般和 moveToPoint: 配合使用。
 其中起始點(diǎn)由 -moveToPoint: 設(shè)置,終止點(diǎn)為 endPoint:,控制點(diǎn)1的坐標(biāo)controlPoint1,控制點(diǎn)2的坐標(biāo)是controlPoint2。
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;

 繪制一段圓弧,center: 原點(diǎn)坐標(biāo)  radius: 半徑   startAngle: 起始角度  endAngle: 終止角度  clockwise 順時(shí)針/逆時(shí)針方向繪制
- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;

 閉合線
- (void)closePath;

 移除所有的點(diǎn),從而有效的刪除所有子路徑
- (void)removeAllPoints;

 追加指定的bezierPath到路徑上
- (void)appendPath:(UIBezierPath *)bezierPath;

 用仿射變換矩陣變換路徑的所有點(diǎn)
- (void)applyTransform:(CGAffineTransform)transform;
圖形上下文中的路徑操作
 填充路徑
- (void)fill;

 各個(gè)點(diǎn)連線
- (void)stroke;

 填充模式,alpha 設(shè)置
 blendMode : https://onevcat.com/2013/04/using-blending-in-ios/
- (void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;

 鏈接模式,alpha設(shè)置
- (void)strokeWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;
 
 圖形繪制超出當(dāng)前路徑范圍,則不可見
- (void)addClip;

QQ消息提示按鈕實(shí)現(xiàn)

下面我們使用UIBezierPath實(shí)現(xiàn)一個(gè)QQ消息提示按鈕的拖拽效果

消息提示按鈕拖拽
拆分動(dòng)畫:
  • 2個(gè)圓(一個(gè)固定圓,一個(gè)拖拽圓)
  • 貝塞爾曲線,求得關(guān)鍵點(diǎn).
  • 固定圓比例縮小
  • 拖拽到一定距離的時(shí)候需要斷開
  • 斷開之后有個(gè)圓的反彈效果bgg
實(shí)現(xiàn)思路拆分步驟(根據(jù)兩個(gè)圓求得關(guān)鍵點(diǎn))
獲取斜邊d以及角度
已知條件
計(jì)算A點(diǎn)

注意:計(jì)算A點(diǎn)坐標(biāo)的時(shí)候,由于屏幕左上角是原點(diǎn)(0, 0),所以要用(x1, y1)坐標(biāo)分別減去對應(yīng)的間距。

計(jì)算B點(diǎn)
計(jì)算C點(diǎn)
計(jì)算D點(diǎn)
計(jì)算O點(diǎn)
計(jì)算P點(diǎn)
#import "ViewController.h"

@interface ViewController ()
//圓1
@property (nonatomic, strong) UIView *view1;
//圓2
@property (nonatomic, strong) UIView *view2;
//shapeLayer圖層
@property (nonatomic, strong) CAShapeLayer *shapeLayer;
//坐標(biāo)記錄
@property (nonatomic, assign) CGPoint oldViewCenter;
@property (nonatomic, assign) CGRect oldViewFrame;
@property (nonatomic, assign) CGFloat r1;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //1.UI.
    [self setUp];
}

-(void)setUp
{
    //添加view1
    _view1 = [[UIView alloc] initWithFrame:CGRectMake(36, CGRectGetHeight(self.view.bounds)-66, 40, 40)];
    _view1.layer.cornerRadius = 20;
    _view1.backgroundColor = [UIColor redColor];
    [self.view addSubview:_view1];
    //添加view2
    _view2 = [[UIView alloc] initWithFrame:_view1.frame];
    _view2.layer.cornerRadius = 20;
    _view2.backgroundColor = [UIColor redColor];
    [self.view addSubview:_view2];
    //添加label
    UILabel *numL = [[UILabel alloc] initWithFrame:_view2.bounds];
    numL.text = @"99";
    numL.textAlignment = NSTextAlignmentCenter;
    numL.textColor = [UIColor whiteColor];
    [_view2 addSubview:numL];
    //添加手勢
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
    [_view2 addGestureRecognizer:pan];
    
    //初始化layer
    _shapeLayer = [CAShapeLayer layer];
    _oldViewFrame = _view1.frame;
    _oldViewCenter = _view1.center;
    _r1 = CGRectGetWidth(_view1.frame)/2;
}

-(void)panAction:(UIPanGestureRecognizer *)ges{
    if (ges.state == UIGestureRecognizerStateChanged) {
        //1.view2跟著手指移動(dòng) --執(zhí)行案例
        _view2.center = [ges locationInView:self.view];
        
        //當(dāng)拖拽到一定距離之后,則移出來
        //那么就是r1半徑縮減到一定距離
        //在caculPoint 方法中,更新r1值
        //再拖拽if中判斷,如果低于9
        if (_r1 < 9) {
            _view1.hidden = YES;
            [_shapeLayer removeFromSuperlayer];
            
        }
        //2.計(jì)算6個(gè)關(guān)鍵點(diǎn),并畫出貝塞爾曲線
        [self caculPoint];
    }else if(ges.state == UIGestureRecognizerStateEnded
             || ges.state == UIGestureRecognizerStateFailed
             || ges.state == UIGestureRecognizerStateCancelled)
    {
        //思考: 回彈時(shí),那些屬性/組件要做調(diào)整
        //view2 位置恢復(fù),shaperLayer消失,
       // [_shapeLayer removeFromSuperlayer];
       // _view2.center= _oldViewCenter;
        
        [_shapeLayer removeFromSuperlayer];
        //加上彈跳效果動(dòng)畫
        __weak typeof(self) weakSelf = self;
        [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.3 initialSpringVelocity:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            weakSelf.view2.center = weakSelf.oldViewCenter;
        } completion:^(BOOL finished) {
            weakSelf.view1.hidden = NO;
            weakSelf.view1.frame = weakSelf.oldViewFrame;
            weakSelf.r1 = weakSelf.oldViewFrame.size.width/2;
            weakSelf.view1.layer.cornerRadius = weakSelf.r1;
        }];
    }
}

-(void)caculPoint{
    //1.初始化已知頂點(diǎn)
    CGPoint center1 = _view1.center;
    CGPoint center2 = _view2.center;
    
    //2.計(jì)算出斜邊d的長度(根據(jù)勾股定理)
    //d= √((x2-x1)?(x2-x1) + (y1-y2)?(y1-y2));
    CGFloat dis = sqrtf(pow((center2.x-center1.x), 2)+pow(center1.y-center2.y, 2));
    
    //3.計(jì)算sin(正弦),cos(余弦)數(shù)據(jù)
    CGFloat sinValue = (center2.x - center1.x)/dis;
    CGFloat cosValue = (center1.y - center2.y)/dis;
    
    //4.半徑
    CGFloat r1 = CGRectGetWidth(_oldViewFrame)/2 - dis/20;
    CGFloat r2 = CGRectGetHeight(_view2.bounds)/2;
    //更新_r1值
    _r1 = r1;
    
    //5.計(jì)算6個(gè)關(guān)鍵點(diǎn)
    CGPoint pA = CGPointMake(center1.x - r1 * cosValue, center1.y - r1 * sinValue);
    CGPoint pB = CGPointMake(center1.x + r1 * cosValue, center1.y + r1 * sinValue);
    CGPoint pC = CGPointMake(center2.x + r2 * cosValue, center2.y + r2 * sinValue);
    CGPoint pD = CGPointMake(center2.x - r2 * cosValue, center2.y - r2 * sinValue);
    
    CGPoint pO = CGPointMake(pA.x + dis/2*sinValue, pA.y - dis/2*cosValue);
    CGPoint pP = CGPointMake(pB.x + dis/2*sinValue, pB.y - dis/2*cosValue);
    
    //6.繪制貝塞爾曲線
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:pA];
    [path addQuadCurveToPoint:pD controlPoint:pO];
    [path addLineToPoint:pC];
    [path addQuadCurveToPoint:pB controlPoint:pP];
    [path closePath];
    
    //7.把路徑添加layer
    //這些寫不可以,因?yàn)槊恳淮瓮献Ь蜁陆ㄒ粋€(gè)CAShapeLayer
    /*
    CAShapeLayer *sh = [[CAShapeLayer alloc]init];
    sh.path = path.CGPath;
    sh.fillColor = [UIColor redColor].CGColor;
    //8.將layer添加到view上--執(zhí)行代碼
    [self.view.layer insertSublayer:sh above:_view2.layer];
    */
    
    if (_view1.hidden) {
        return;
    }
    
    _shapeLayer.path = path.CGPath;
    _shapeLayer.fillColor = [UIColor redColor].CGColor;
    [self.view.layer insertSublayer:_shapeLayer below:_view2.layer];
    
    //8.重新計(jì)算view1的位置---執(zhí)行代碼.
    _view1.center = _oldViewCenter;
    _view1.bounds = CGRectMake(0, 0, r1*2, r1*2);
    _view1.layer.cornerRadius = r1;
    //發(fā)生錯(cuò)誤! 修改r1的計(jì)算才能正常顯示
    //CGFloat r1 = CGRectGetWidth(_oldViewFrame)/2 - dis/20;
}

@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容