iOS之核心動畫

来源:https://www.cnblogs.com/xujinzhong/archive/2018/02/09/8436240.html
-Advertisement-
Play Games

一、核心動畫概念 -導入QuartzCore.framework框架 1⃣ 開發步驟1.初始化一個動畫對象(CAAnimation)並且設置一些動畫相關屬性 2.CALayer中很多屬性都可以通過CAAnimation實現動畫效果,包括:opacity、position、transform、boun ...


1.將動畫的所有方法封裝到一個類裡面

MyCAHelper.h
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>

#define kCAHelperAlphaAnimation @"opacity"; // 淡入淡出動畫
#define kCAHelperScaleAnimation @"transform.scale"; // 比例縮放動畫
#define kCAHelperRotationAnimation @"transform.rotation"; // 旋轉動畫
#define kCAHelperPositionAnimation @"position"; // 平移位置動畫

@interface MyCAHelper : NSObject

#pragma mark - 基本動畫統一調用方法
+ (CABasicAnimation *)myBasicAnimationWithType:(NSString *)animationType
duration:(CFTimeInterval)duration
from:(NSValue *)from
to:(NSValue *)to
autoRevereses:(BOOL)autoRevereses;

#pragma mark - 關鍵幀動畫方法
#pragma mark 搖晃動畫
+ (CAKeyframeAnimation *)myKeyShakeAnimationWithDuration:(CFTimeInterval)duration
angle:(CGFloat)angle
repeatCount:(CGFloat)repeatCount;

#pragma mark 貝塞爾路徑動畫
+ (CAKeyframeAnimation *)myKeyPathAnimationWithDuration:(CFTimeInterval)duration
path:(UIBezierPath *)path;

#pragma mark 彈力模擬動畫
+ (CAKeyframeAnimation *)myKeyBounceAnimationFrom:(CGPoint)from
to:(CGPoint)to
duration:(CFTimeInterval)duration;

@end
MyCAHelper.m
#import "MyCAHelper.h"

@implementation MyCAHelper

#pragma mark - 基本動畫統一調用方法
+ (CABasicAnimation *)myBasicAnimationWithType:(NSString *)animationType
duration:(CFTimeInterval)duration
from:(NSValue *)from
to:(NSValue *)to
autoRevereses:(BOOL)autoRevereses
{
        // 1. 實例化一個CA動畫對象
        CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:animationType];
        
        // 2. 設置動畫屬性
        [anim setDuration:duration];
        
        [anim setFromValue:from];
        [anim setToValue:to];
        
        [anim setAutoreverses:autoRevereses];
        
        return anim;
}

#pragma mark - 關鍵幀動畫方法
#pragma mark 搖晃動畫
+ (CAKeyframeAnimation *)myKeyShakeAnimationWithDuration:(CFTimeInterval)duration
angle:(CGFloat)angle
repeatCount:(CGFloat)repeatCount
{
        // 1. 初始化動畫對象實例
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
        
        // 2. 設置動畫屬性
        [anim setDuration:duration];
        
        [anim setValues:@[@(angle), @(-angle), @(angle)]];
        
        [anim setRepeatCount:repeatCount];
        
        return anim;
}

#pragma mark 貝塞爾路徑動畫
+ (CAKeyframeAnimation *)myKeyPathAnimationWithDuration:(CFTimeInterval)duration
path:(UIBezierPath *)path
{
        // 1. 初始化動畫對象實例
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        
        // 2. 設置動畫屬性
        [anim setDuration:duration];
        
        [anim setPath:path.CGPath];
        
        return anim;
}

#pragma mark 彈力模擬動畫
+ (CAKeyframeAnimation *)myKeyBounceAnimationFrom:(CGPoint)from
to:(CGPoint)to
duration:(CFTimeInterval)duration
{
        // 是一個基於路徑的動畫
        // 首先定義一個路徑,記錄彈力模擬的整個路徑
        CGMutablePathRef path = CGPathCreateMutable();
        
        // 彈力模擬路徑創建代碼
        // 計算起始點與目標點之間的位置偏移量,這個偏移量的目的是為了能夠計算出小球第一次延伸的長度
        CGFloat offsetX = from.x - to.x;
        CGFloat offsetY = from.y - to.y;
        
        // 1. 移動到起始點
        CGPathMoveToPoint(path, NULL, from.x, from.y);
        // 2. 將目標點的坐標添加到路徑之中
        CGPathAddLineToPoint(path, NULL, to.x, to.y);
        // 3. 設置小球的彈力因數
        CGFloat offsetDivider = 4.0f;
        
        while (YES) {
                // 加延伸方向的路徑
                CGPathAddLineToPoint(path, NULL, to.x + offsetX / offsetDivider,
                to.y + offsetY / offsetDivider);
                
                // 再次將目標點添加到路徑
                CGPathAddLineToPoint(path, NULL, to.x, to.y);
                
                // 彈力因數遞增,保證越來越接近目標點
                offsetDivider += 6.0f;
                
                // 當小球的當前位置距離目標點足夠小,我們退出迴圈
                if ((abs(offsetX / offsetDivider) < 10.0f)
                && (abs(offsetY / offsetDivider) < 10.0f)) {
                
                    break;
                }
        }

        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        [anim setPath:path];
        
        // 釋放路徑
        CGPathRelease(path);
        
        [anim setDuration:duration];
        
        return anim;
}

@end
#import "ViewController.h"
#import "MyCAHelper.h"

@interface ViewController ()
{
        UIView *_demoView;
        CGPoint location;
}
@end

@implementation ViewController

- (void)viewDidLoad
{
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        [self.view setBackgroundColor:[UIColor lightGrayColor]];
        
        _demoView = [[UIView alloc]initWithFrame:CGRectMake(50, 50, 100, 100)];
        [_demoView setBackgroundColor:[UIColor whiteColor]];
        [self.view addSubview:_demoView];
}

- (void)didReceiveMemoryWarning
{
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
        UITouch *touch = [touches anyObject];
        location = [touch locationInView:self.view];
        
        // [_demoView setCenter:location];
        /** 
        1.測試基本動畫
        */
        // CABasicAnimation *anim = [self testBasic1];
        // [anim setRepeatCount:3];
        // 
        // [_demoView.layer addAnimation:anim forKey:nil];
        /**
        2.測試彈力模擬動畫效果
        */
        // [_demoView.layer addAnimation:[self test1:_demoView.center to:location] forKey:nil];
        /**
        3.測試路徑關鍵幀動畫
        */
        // [_demoView.layer addAnimation:[self test2] forKey:nil];
        // [_demoView.layer addAnimation:[self test4:_demoView.center to:location] forKey:nil];
        /**
        4.測試搖晃關鍵幀動畫
        */
        // 點擊屏幕,開始搖晃,再次點擊,停止搖晃
        // CAAnimation *anim = [_demoView.layer animationForKey:@"shakeAnimation"];
        // if (anim) {
        // [_demoView.layer removeAnimationForKey:@"shakeAnimation"];
        // } else {
        // [_demoView.layer addAnimation:[self test5] forKey:@"shakeAnimation"];
        // }
        CAKeyframeAnimation *anim = [self test1:_demoView.center to:location];
        [_demoView.layer addAnimation:anim forKey:nil];
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
        // 需要在這裡對不同對象的動畫方法進行完成處理!
        [_demoView setCenter:location];
        NSLog(@"%@", NSStringFromCGPoint(_demoView.center));
}

#pragma mark - 重構方法測試
#pragma mark 測試貝塞爾路徑關鍵幀動畫
- (CAKeyframeAnimation *)test5
{
        return [MyCAHelper myKeyShakeAnimationWithDuration:0.2 angle:M_PI_4 / 18 repeatCount:MAXFLOAT];
}

#pragma mark 測試貝塞爾路徑關鍵幀動畫
- (CAKeyframeAnimation *)test4:(CGPoint)from to:(CGPoint)to
{
        UIBezierPath *path = [UIBezierPath bezierPath];
        
        // 有兩個控制點去擠出的曲線,能擠出S型的曲線
        [path moveToPoint:from];
        [path addCurveToPoint:to controlPoint1:CGPointMake(320, 0) controlPoint2:CGPointMake(0, 460)];
        
        return [MyCAHelper myKeyPathAnimationWithDuration:2.0 path:path];
}

#pragma mark 測試貝塞爾路徑關鍵幀動畫
- (CAKeyframeAnimation *)test3:(CGPoint)from to:(CGPoint)to
{
        UIBezierPath *path = [UIBezierPath bezierPath];
        
        // 只有一個控制點去擠出的曲線
        [path moveToPoint:from];
        [path addQuadCurveToPoint:to controlPoint:CGPointMake(320, 230)];
        
        return [MyCAHelper myKeyPathAnimationWithDuration:2.0 path:path];
}

#pragma mark 測試路徑關鍵幀動畫
- (CAKeyframeAnimation *)test2
{
        UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];
        return [MyCAHelper myKeyPathAnimationWithDuration:2.0 path:path];
}

#pragma mark 測試彈力模擬動畫效果
- (CAKeyframeAnimation *)test1:(CGPoint)from to:(CGPoint)to
{
        CAKeyframeAnimation *anim = [MyCAHelper myKeyBounceAnimationFrom:from to:to duration:1.5];
        [anim setFillMode:kCAFillModeForwards];
        [anim setRemovedOnCompletion:NO];
        
        [anim setDelegate:self];
        
        return anim;
}

- (CABasicAnimation *)testBasic1
{
        return [MyCAHelper myBasicAnimationWithType:@"opacity" duration:1.0 from:@(1.0) to:@(0.3) autoRevereses:YES];
}

@end

一、核心動畫概念

-導入QuartzCore.framework框架

1⃣ 開發步驟
1.初始化一個動畫對象(CAAnimation)並且設置一些動畫相關屬性

2.CALayer中很多屬性都可以通過CAAnimation實現動畫效果,包括:opacity、position、transform、bounds、contents等(可以在API文檔中搜索:CALayer Animatable Properties)

3.添加動畫對象到層(CALayer)中,開始執行動畫

4.通過調用CALayer的addAnimation:forKey增加動畫到層(CALayer)中,這樣就能觸發動畫。通過調用removeAnimationForKey可以停止層中的動畫

5.Core Animation的動畫執行過程都是後臺操作的,不會阻塞主線程

2⃣ 屬性
1.duration:動畫的持續時間

2.repeatCount:重覆次數(HUGE_VALF、MAX FLOAT無限重覆)

3.repeatDuration:重覆時間(用的很少)

4.removedOnCompletion:預設為Yes。動畫執行完後預設會從圖層刪除掉

5.fillMode
6.biginTime
7.timingFunction:速度控制函數,控制動畫節奏

8.delegate


二、基礎動畫(CABasicAnimation)
如果只是實現簡單屬性變化的動畫效果,可以使用UIView的塊動畫替代基本動畫

1⃣ 屬性說明
-fromValue:keyPath相應屬性值的初始值

-toValue:keyPath相應屬性的結束值

2⃣ 動畫過程說明:

-隨著動畫的就行,在duration的持續時間內,keyPath相應的屬性值從fromValue漸漸變為toValue

-keyPath內容是CALayer的可動畫Animation屬性

-如果fillMode=kCAFillModeForwards同時removedOnCompletion=NO,那麼在動畫執行完畢後,圖層會保持顯示動畫執行後的狀態,但在實質上,圖層的屬性值還是動畫執行前的初始值,並沒有真正改變

3⃣ 代碼實現
位移需要考慮目標點設定的問題

 

三、關鍵幀動畫(CAKeyframeAnimation)

基礎動畫只能從一個值到另一個值,關鍵幀動畫可以用一個數組保存一系列值

1⃣ 屬性說明
-values:所有的值(用的較少)

-path:路線(如果設置了path,那麼values將被忽略)

-keyTimes:可以為對應的關鍵幀制定對應的時間點,取值範圍是0到1.0

2⃣ 過程步驟
-初始化自定義視圖

-點擊屏幕,執行動畫

1.指定點平移動畫(values)

2.路徑平移動畫(path C語言框架CGMutablePathRef,需要手動釋放記憶體)

3.貝塞爾路徑動畫(OC框架UIBezierPath)

4.搖晃動畫(修改旋轉角度)

3⃣ 代碼重構
如上代碼,重構在了一起

四、動畫組
動畫是可以併發執行的

-定義一個group組

-定義動畫
-將動畫加入group組

-可以給組設置屬性

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
        UITouch *touch = [touches anyObject];
        CGPoint location = [touch locationInView:self.view];
        
        [_demoView setBackgroundColor:[UIColor redColor]];
        
        // 1. 定義動畫組
        CAAnimationGroup *group = [CAAnimationGroup animation];
        // 定義一組動畫
        // 淡入淡出動畫
        CABasicAnimation *alpha = [MyCAHelper myBasicAnimationWithType:kCAHelperAlphaAnimation duration:1.0 from:@(1.0) to:@(0.3) autoRevereses:YES];
        // 旋轉動畫
        CABasicAnimation *rotation = [MyCAHelper myBasicAnimationWithType:kCAHelperRotationAnimation duration:2.0 from:@(-M_PI_2) to:@(M_PI_2) autoRevereses:NO];
        // 縮放動畫
        CABasicAnimation *scale = [MyCAHelper myBasicAnimationWithType:kCAHelperScaleAnimation duration:0.5 from:@(1.0) to:@(0.1) autoRevereses:YES];
        
        // 關鍵幀路徑動畫,彈力模擬動畫效果
        CAKeyframeAnimation *path = [self test1:_demoView.center to:location];
        
        // 2. 設置動畫組屬性
        [group setAnimations:@[alpha, path, rotation, scale]];
        
        // 設置動畫的時長
        [group setDuration:4.0];
        
        // 3. 將動畫組添加到圖層
        [_demoView.layer addAnimation:group forKey:nil];
}

五、轉場動畫-CATransition
1⃣屬性說明
-type:動畫過渡類型

-subtype:動畫過渡方向

-startProgress:動畫起點(在整體動畫的百分比)

-endProgress:動畫終點(在整體動畫的百分比)

-增加一個轉場演示視圖

-增加輕掃手勢
-在輕掃手勢方法中

1.更改演示視圖內容

2.創建轉場動畫效果

3.將轉場動畫添加到視圖的圖層

// 輕掃手勢操作
- (void)swipeAction:(UISwipeGestureRecognizer *)sender
{
        // 通過輕掃手勢,讓切換出來的視圖是藍色的
        if (_demoView.tag == 0) {
        [_demoView setBackgroundColor:[UIColor blueColor]];
        [_demoView setTag:1];
        } 
        else 
        {
        [_demoView setBackgroundColor:[UIColor redColor]];
        [_demoView setTag:0];
        }
        
        // 根據視圖內容我們來實現專場動畫
        CATransition *anim = [CATransition animation];
        // 設置專場動畫的過渡類型
        [anim setType:@"cameraIrisHollowClose"];
        // 需要根據手勢的方向,來決定專場動畫的動畫方向
        // 註意:在轉場動畫中,動畫方向的左右是和手勢的方向相反的
        if (sender.direction == UISwipeGestureRecognizerDirectionLeft) {
        [anim setSubtype:kCATransitionFromRight];
        } else {
        [anim setSubtype:kCATransitionFromLeft];
        }
        
        [_demoView.layer addAnimation:anim forKey:nil];
}

- (void)viewDidLoad
{
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        // 1. 實例化自定義視圖
        _demoView = [[UIView alloc]initWithFrame:self.view.bounds];
        [_demoView setBackgroundColor:[UIColor redColor]];
        
        [self.view addSubview:_demoView];
        
        // 2. 增加輕掃手勢
        UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]
        initWithTarget:self
        action:@selector(swipeAction:)];
        [swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
        [_demoView addGestureRecognizer:swipeLeft];
        
        UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
        initWithTarget:self
        action:@selector(swipeAction:)];
        [swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
        [_demoView addGestureRecognizer:swipeRight];
}

六、UIView的轉場動畫-雙視圖

+(void)transitionWithView:(UIView*)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOL finished))completion;

1⃣參數說明
-duration:動畫的持續時間

-view:需要進行轉場動畫的視圖

-options:轉場動畫的類型

-animations:將改變視圖屬性的代碼放在這個Block里

-completion:動畫結束後,自動調用的Block

@interface ViewController ()
{
        UIImageView *_demoImageView;
        UIImageView *_demoImageView2;
}
@end

@implementation ViewController

- (void)viewDidLoad
{
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        // 實例化第一個UIImageView的對象
        _demoImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"1.jpg"]];
        [self.view addSubview:_demoImageView];
        
        // 實例化第二個UIImageView對象
        // 註意:在雙視圖轉場動畫中,不要將第二個視圖添加到主視圖
        _demoImageView2 = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"2.jpg"]];
}

- (void)didReceiveMemoryWarning
{
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
        // 單擊屏幕的時候,實現轉場動畫效果
        [self animation1];
}

#pragma mark - 單視圖的轉場動畫
- (void)animation2
{
        UIImageView *from;
        UIImageView *to;
        
        if (_demoImageView.superview) {
        from = _demoImageView;
        to = _demoImageView2;
        } 
        else 
        {
        from = _demoImageView2;
        to = _demoImageView;
        }
        
        [UIView transitionFromView:from toView:to duration:1.0f options:UIViewAnimationOptionTransitionCrossDissolve completion:^(BOOL finished) {
        NSLog(@"image view1 的主視圖: %@", _demoImageView.superview);
        NSLog(@"image view2 的主視圖: %@", _demoImageView2.superview);
        }];
}

#pragma mark - 單視圖的轉場動畫
- (void)animation1
{
        [UIView transitionWithView:_demoImageView duration:1.0f options:UIViewAnimationOptionTransitionCurlUp animations:^{
        // 在動畫塊代碼中設置視圖內容變化
                if (_demoImageView.tag == 0) {
                        [_demoImageView setImage:[UIImage imageNamed:@"2.jpg"]];
                        [_demoImageView setTag:1];
                } 
                else 
                {
                        [_demoImageView setImage:[UIImage imageNamed:@"1.jpg"]];
                        [_demoImageView setTag:0];
                }
        } completion:nil];
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 結構語言分類 DDL(數據定義語言) create drop alter 創建刪除以及修改資料庫,表,存儲過程,觸發器,索引.... DML(數據操作語言) insert delete update 用來操作資料庫中的數據 DQL(數據查詢語言) select 用來查詢資料庫中的數據 DCL(數據控 ...
  • 背景 原文地址(http://www.cnblogs.com/wenBlog/p/8435229.html) 最近針對我們的處理器出現了一系列的嚴重的bug。這種bug導致了兩個情況,就是熔斷和幽靈。 這就是這幾天鬧得人心惶惶的CPU大Bug。消息顯示,以英特爾處理器為代表的現代CPU中,存在可以導 ...
  • http://dcx.sybase.com/1101/en/dbprogramming_en11/ianywhere-data-sqlanywhere-saconnection-getschem6330755502-0.html http://razorsql.com/articles/sybase ...
  • 一、概述 mongodb是最接近關係型資料庫的NOSQL資料庫,它的存儲方式非常的靈活;以至於你會將它看成是一個經過冗餘過的關係型資料庫的表,這也是Mongodb原子性的一個特征。由於沒有關係型資料庫的表之間的關聯關係和事務性所以Mongodb插入和更新的效率非常的高,同時也支持索引。我們在查詢的時 ...
  • ViewPager中切換界面Fragment被銷毀的問題分析 使用ViewPager+Fragment實現界面切換,當界面數量大於3時,出現二次滑動後數據消失的情況,下麵由Fragment生命周期進行分析 簡單解析: 使用pager=3進行測試,當界面由2切換到1的時候,3界面對應的Fragment ...
  • 今天同事誤上傳一個庫,然後又刪除了。。。 我剛好把他上傳的庫給down下來了。。。然後項目一直報錯,clean。。。重新編譯。。。刪build文件。。。。全都不管用 好幾個人研究了好久,只能猜測是緩存問題。。。把項目的緩存全刪了沒用。。。。那應該是gradle緩存的問題。。。 可以我電腦上的grad ...
  • There may be a situation, when you need to execute a block of code several number of times. In general, statements are executed sequentially: The firs ...
  • 目錄: 一、Viewpager的簡單介紹 二、簡單的Viewpager使用 三、簡單顯示圖片的Viewpager實現 四、廣告圖的實現及Viewpager指示器(小圓點)的實現 五、APP引導頁的實現 一、ViewPager介紹 官方文檔解釋: Layout manager that allows ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...