模仿我的淘寶雙波浪線和翻頁效果

淘寶我的界面波浪線

先看圖片
模仿淘寶.gif

demo沒進行封裝,內容的實現主要使用了CADisplayLink定時器,UIBezierPath結合CAShaperLayer 實現的雙波浪效果,用了Model轉場動畫實現的下拉跳轉界面

整體來說不是太難 難的地方在于用UIBezierPath繪制下面的弧形時需要手動計算弧形的坐標。

實現方法 :

一、 首先要知道下面這個公式:
y = Asin(wx+Q) + S;
55969228-C38F-42FC-8B4D-25D49C54EE4F.png

對應的曲線是這樣的

u=2166549996,3486693099&fm=23&gp=0.jpg
A 表示峰值,忘記數學怎么稱呼了(知道的大咖給說下,謝謝) 及最大值和最小值 由于sin(wx + Q)的區間是[-1,1];所以Asin(wx + Q)的區間就是[-A,A];聽朋友說叫振幅

W 表示周期 w越大周期T越小 我取的是0.04;
Q 是用來調整曲線的左右位置
S 是用來調整上下的位置
二、繪制波浪線
- (UIBezierPath *)getWavePath:(CGFloat)A W:(CGFloat)w d:(CGFloat)d dong:(CGFloat)dong{
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, 0)];
    [path addLineToPoint:CGPointMake(0, 50)];
    
    for (int i = 0; i < [UIScreen mainScreen].bounds.size.width; i++) {
        
        // 這個是波浪線繪制的主要代碼   
        CGFloat y = A*sinf(i*w +dong+self.dong)+d;
        
        
        [path addLineToPoint:CGPointMake(i, y)];
    }
    
    [path addLineToPoint:CGPointMake([UIScreen mainScreen].bounds.size.width, 0)];
    [path closePath];
    return path;

}

接著先創建一個TableView的頭視圖View

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 260)];
    view.backgroundColor = [UIColor whiteColor];
    self.headerView = view;
    self.tableView.tableHeaderView = self.headerView;

創建CAShaperLayer 添加到TableView的頭視圖上 這樣就創建了一個波浪線

    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.fillColor = [UIColor whiteColor].CGColor;
    layer.frame = view.bounds;
    layer.opacity = 0.3; // 透明度
    layer.shouldRasterize = YES;  // 加個注釋 這個是讓曲線能平滑過渡,防止有鋸齒狀
    layer.path = [self getWavePath:8 W:0.04 d:25+60 dong:0].CGPath;
    self.shapeLayer = layer;
    [view.layer addSublayer:layer];

因為淘寶有兩個波浪線 還需要創建一個 沒封裝 所以又粘貼了一遍

  CAShapeLayer *layer1 = [CAShapeLayer layer];
    layer1.fillColor = [UIColor whiteColor].CGColor;
    layer1.frame = view.bounds;
    layer1.opacity = 0.3;
    layer1.shouldRasterize = YES;
    layer1.path = [self getWavePath:8 W:0.04 d:29+60 dong:10].CGPath;
    self.shapeLayer1 = layer1;
    [view.layer addSublayer:layer1];

但是淘寶的波浪會動啊 怎么辦? 這個時候我們就需要定時器 CADisplayLink 來控制波浪的波動,這個主要用來動畫的處理,NSTimer精準度沒這么高,具體的區別請看:(CADisplayLink

    _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(disPlayLink:)];
    [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    
- (void)disPlayLink:(CADisplayLink *)displayLink {
    self.dong = self.dong+0.05;
    self.shapeLayer.path = [self getWavePath:8 W:0.04 d:25+60 dong:0].CGPath;
    self.shapeLayer1.path = [self getWavePath:8 W:0.04 d:29+60 dong:10].CGPath;
}
    

這樣你會神器的發現雙波浪動畫就實現了

三、繪制下面的圓?。ň唧w點的位置可以根據自己的方法計算)
5550717FD6EF24BA22462D927FD0F25D.jpg

代碼

- (UIBezierPath *)getLayerBezierPath {

    CGFloat width = [UIScreen mainScreen].bounds.size.width;
    CGFloat R = 25+pow(width, 2)/400.0f;
    CGPoint centerArc = CGPointMake(width/2.0f,260-R);
    
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint:CGPointMake(0, 0)];
    [bezierPath addLineToPoint:CGPointMake(0, 210)];
    
    // acos() 這個就是數學里面的arccos();
    [bezierPath addArcWithCenter:centerArc radius:R startAngle:acos(width/(2*R)) endAngle:(M_PI-acos(width/(2*R))) clockwise:YES];
    [bezierPath addLineToPoint:CGPointMake(width, 210)];
    [bezierPath addLineToPoint:CGPointMake(width, 0)];
    [bezierPath closePath];
    
    return bezierPath;

}

創建一個layer扔到headerView上

    CAShapeLayer *layer2 = [CAShapeLayer layer];
    layer2.fillColor = [UIColor orangeColor].CGColor;
    layer2.frame = view.bounds;
    layer2.shouldRasterize = YES;
    layer2.path = [self getLayerBezierPath].CGPath;
    [view.layer addSublayer:layer2];

四、下面開始做轉場動畫

1、創建一個類、繼承NSObject 下面是.h中的代碼

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger, CLImitationTaoBaoModelType) {
    CLImitationTaoBaoModelTypePresent,
    CLImitationTaoBaoModelTypeDismiss
};


@interface CLImitationTaoBao : NSObject <UIViewControllerAnimatedTransitioning>

+ (CLImitationTaoBao *)imitationTaoBao:(CLImitationTaoBaoModelType)modelType;


@end

2、實現兩個協議


// 具體動畫在這里面操作
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext;

// 動畫跳轉時長
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext 

3、轉場動畫的操作過程()


// 跳轉時的方法
- (void)present:(id<UIViewControllerContextTransitioning>)transitionContext {

    UIView *fromeView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    UIView *containerView = [transitionContext containerView];
    
    [containerView addSubview:fromeView];
    [containerView addSubview:toView];
    
    fromeView.frame = containerView.frame;
    toView.frame = CGRectMake(0, -containerView.frame.size.height, containerView.frame.size.width, containerView.frame.size.height);
    
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
       
        fromeView.frame = CGRectMake(0, containerView.frame.size.height*4/5.0f, containerView.frame.size.width, containerView.frame.size.height);
        toView.frame = CGRectMake(0, 0, containerView.frame.size.width, containerView.frame.size.height);
        
    } completion:^(BOOL finished) {
        
        [transitionContext completeTransition:YES];
        
    }];
    
}
// 返回時的方法
- (void)dismiss:(id<UIViewControllerContextTransitioning>)transitionContext {
    UIView *fromeView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    UIView *containerView = [transitionContext containerView];
    
    [containerView addSubview:fromeView];
    [containerView addSubview:toView];
    
    fromeView.frame = containerView.frame;
    toView.frame = CGRectMake(0, containerView.frame.size.height, containerView.frame.size.width, containerView.frame.size.height);
    
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        
        fromeView.frame = CGRectMake(0, -containerView.frame.size.height, containerView.frame.size.width, containerView.frame.size.height);
        toView.frame = CGRectMake(0, 0, containerView.frame.size.width, containerView.frame.size.height);
        
    } completion:^(BOOL finished) {
        
        [transitionContext completeTransition:YES];
        
    }];
    
}

+ (CLImitationTaoBao *)imitationTaoBao:(CLImitationTaoBaoModelType)modelType {
    
    CLImitationTaoBao *imitation = [[CLImitationTaoBao alloc] init];
    imitation.modelType = modelType;
    return imitation;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {

    
    if (self.modelType == CLImitationTaoBaoModelTypePresent) {
    
        [self present:transitionContext];
        
    } else {
    
        [self dismiss:transitionContext];
        
    }
    
    
    
    
}


- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
    
    
    return 0.5;
}

轉場動畫的具體學習以后再做筆記。

最后附Demo地址:https://github.com/qcl901028/myTaoBao

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1、通過CocoaPods安裝項目名稱項目信息 AFNetworking網絡請求組件 FMDB本地數據庫組件 SD...
    陽明AGI閱讀 16,018評論 3 119
  • 用到的組件 1、通過CocoaPods安裝 2、第三方類庫安裝 3、第三方服務 友盟社會化分享組件 友盟用戶反饋 ...
    SunnyLeong閱讀 14,713評論 1 180
  • 在一起一年了,哈哈,每次跟他說起來,都覺得不應該才一年,感覺生活在一起很久了。 琛哥,是那種三分正經三分無賴四分裝...
    月如新織閱讀 820評論 0 4
  • 春風如故盼香濃 杏影搖曳 桃花緋紅 輕落泥土似無情 未憐倩影佳人瘦 已下眉梢 卻上心頭 應有無盡相思愁
    且看浮生閱讀 368評論 0 3
  • 你要穿越, 多少蒼穹之上; 仰望, 多少星點斑斕。 他們飛走了, 思想死了…… ———寫于2011年5月30
    Grace_h13閱讀 281評論 0 0