《iOS動(dòng)畫》讀書筆記·顯示層動(dòng)畫

《iOS動(dòng)畫》讀書筆記·前序
《iOS動(dòng)畫》讀書筆記·顯示層動(dòng)畫
《iOS動(dòng)畫》讀書筆記·內(nèi)容層動(dòng)畫
《iOS動(dòng)畫》讀書筆記·轉(zhuǎn)場動(dòng)畫

UIView常用動(dòng)畫合集圖解

UIView常用動(dòng)畫合集.jpg

UIView顯示層動(dòng)畫效果的實(shí)質(zhì)還是通過修改UIView的各種屬性來實(shí)現(xiàn)的。

UIView動(dòng)畫效果經(jīng)常涉及的屬性

frame bounds center
alpha backgroundColor transform

這里說一下:transform

UIView有一個(gè)特別重要的屬性transform,該屬性繼承自CGAffineTransform,“CG”實(shí)際上是CoreGraphics框架的縮寫??梢?code>transform屬性是核心繪圖框架與UIView之間的橋梁。transform最常用的三種動(dòng)畫分別是縮放、旋轉(zhuǎn)、位移。

動(dòng)畫設(shè)置:閉包形式

UIView.animate(withDuration: 0.5) {

    self.loginBT?.center = CGPoint(x: kScreenW/2.0, y: kScreenH/2.0)
}

UIView.animate(withDuration: 0.5, animations: {
    
}) { (true) in
    
}

UIView.animate(withDuration: 0.5, delay: 0.2, options: UIView.AnimationOptions.curveEaseOut, animations: {
    
}) { (true) in
    
}

動(dòng)畫設(shè)置:方法形式

UIView.beginAnimations(nil, context: nil)//動(dòng)畫開始

UIView.setAnimationDuration(0.5)//動(dòng)畫周期設(shè)置
     
UIView.setAnimationCurve(UIView.AnimationCurve.easeInOut)//動(dòng)畫屬性

UIView.setAnimationDelay(1)//動(dòng)畫延遲執(zhí)行時(shí)間,比如動(dòng)畫啟動(dòng)之后,實(shí)際展示效果要等1s之后才顯示出來

UIView.setAnimationsEnabled(true)//動(dòng)畫是否能用

UIView.setAnimationRepeatAutoreverses(true)//動(dòng)畫是否有重復(fù)返回效果

UIView.setAnimationRepeatCount(5)//動(dòng)畫重復(fù)次數(shù)

// 動(dòng)畫具體要做的處理
...

UIView.commitAnimations()//動(dòng)畫提交

動(dòng)畫屬性設(shè)置加速、減速效果

public enum AnimationCurve : Int {
    case easeInOut  //動(dòng)畫開始和結(jié)束時(shí)呈現(xiàn)減速效果
    
    case easeIn     //動(dòng)畫開始時(shí)呈現(xiàn)減速效果
    
    case easeOut    //動(dòng)畫結(jié)束時(shí)呈現(xiàn)減速效果
    
    case linear     //動(dòng)畫整個(gè)周期內(nèi)速度一致、勻速運(yùn)動(dòng)
}

動(dòng)畫回調(diào)方法

delegate 回調(diào)方法

optional public func animationDidStart(_ anim: CAAnimation)
optional public func animationDidStop(_ anim: CAAnimation, finished flag: Bool)

setAnimationDidStop自定義回調(diào)方法

UIView.setAnimationDidStop(#selector(self.animationEnd))
    
@objc func animationEnd() {
    //...
}

初級(jí)動(dòng)畫合集 - 實(shí)戰(zhàn)

這部分內(nèi)容比較簡單,這里主要做介紹,最后提供一個(gè)簡單的組合動(dòng)畫展示一下(效果如下):

組合動(dòng)畫示例.gif

開始前,定義全局常量:

let kScreenW = UIScreen.main.bounds.size.width //屏幕寬
let kScreenH = UIScreen.main.bounds.size.height//屏幕高

位置動(dòng)畫

場景:界面上有一個(gè)按鈕,頁面加載完成時(shí)按鈕從底部彈出。首先viewDidLoad()里面初始化一個(gè)button,然后在viewDidAppear()方法里使用閉包形式改變buttonframecenter兩種方式實(shí)現(xiàn)這個(gè)效果。

viewDidAppear() 表明所有的視圖已經(jīng)可見

var loginBT:UIButton?
    
override func viewDidLoad() {
   super.viewDidLoad()
   
   // Do any additional setup after loading the view.
   
   self.view.backgroundColor = UIColor.white
   
   loginBT = UIButton.init(frame: CGRect(x: 20, y: kScreenH, width: self.view.bounds.width-40
       , height: 50))
   loginBT?.backgroundColor = UIColor(red: 50/255.0, green: 185/255.0, blue: 170/255.0, alpha: 1.0)
   loginBT?.setTitle("登錄", for: .normal)
   self.view.addSubview(loginBT!)
}

override func viewDidAppear(_ animated: Bool) {
   super.viewDidAppear(animated)
   
   //1. 改變frame的形式
   UIView.animate(withDuration: 0.5) {
       self.loginBT?.frame = CGRect(x: self.loginBT!.frame.origin.x, y: kScreenH - 200, width: self.loginBT!.frame.size.width, height: self.loginBT!.frame.size.height)
   }
   
   //2. 改變center的形式
UIView.animate(withDuration: 0.5) {
   self.loginBT?.center = CGPoint(x: kScreenW/2.0, y: kScreenH/2.0)
}

幾何形狀動(dòng)畫

設(shè)置屬性boundstransform(scaleX:)

位置 + 形狀動(dòng)畫

func animateFrame() {
   UIView.animate(withDuration: 0.5) {
       self.loginBT?.frame = CGRect(x: 50, y:  400, width: self.loginBT!.frame.size.width*0.7, height: self.loginBT!.frame.size.height*1.2)
   }
}

淡入淡出動(dòng)畫

設(shè)置alpha透明度實(shí)現(xiàn)這一效果:初始時(shí)透明度設(shè)置為0,即隱藏狀態(tài),在動(dòng)畫執(zhí)行效果中將透明度設(shè)置為1.0

顏色漸變動(dòng)畫

設(shè)置backgroundColor實(shí)現(xiàn)這一效果:在動(dòng)畫執(zhí)行效果中改變顏色值

縮放動(dòng)畫

func transformScale() {
   UIView.beginAnimations(nil, context: nil)
   UIView.setAnimationDuration(1.0)
   self.loginBT?.transform = CGAffineTransform(scaleX: 0.7, y: 1.2)
   UIView.commitAnimations()
}

旋轉(zhuǎn)動(dòng)畫

swift中pi表示一個(gè)圓360°,.pi/4就是旋轉(zhuǎn)90°

public static var pi: CGFloat { get }

func transformAngle() {

   UIView.animate(withDuration: 1) {
       
       self.loginBT?.transform = CGAffineTransform(rotationAngle: .pi/4)
   }
}

位移動(dòng)畫

設(shè)置當(dāng)前view相對(duì)于X,Y軸偏移了多少。如 CGAffineTransform(translationX: 0, y: -200),X軸方向沒有偏移,Y軸方向向上偏移了200

func transformXY() {
   UIView.animate(withDuration: 1) {
       self.loginBT?.transform = CGAffineTransform(translationX: 0, y: -200)
   }
}

組合動(dòng)畫

想讓這個(gè)view飛到屏幕外面去,在飛行過程中旋轉(zhuǎn)它,改變它的大小和透明度

func groupAnimation() {
   
   UIView.animate(withDuration: 1) {
       self.loginBT?.frame = CGRect(x: kScreenW, y: 0, width: self.loginBT!.frame.size.width*0.1, height: self.loginBT!.frame.size.height*0.1)
       self.loginBT?.transform = CGAffineTransform(rotationAngle: .pi)
       self.loginBT?.alpha = 0
   }
}

關(guān)鍵幀動(dòng)畫

UIView初級(jí)動(dòng)畫中都是通過修改當(dāng)前UI控件的各種屬性來實(shí)現(xiàn)想要的動(dòng)畫效果,而關(guān)鍵幀動(dòng)畫只需要設(shè)置動(dòng)畫的幾個(gè)關(guān)鍵的顯示幀。

關(guān)鍵方法

@available(iOS 7.0, *)
    open class func animateKeyframes(withDuration duration: TimeInterval, delay: TimeInterval, options: UIView.KeyframeAnimationOptions = [], animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil)

duration    // 動(dòng)畫執(zhí)行周期
delay       // 動(dòng)畫延遲執(zhí)行時(shí)間
options     // 動(dòng)畫執(zhí)行效果
animations  // 關(guān)鍵幀添加處
completion  // 動(dòng)畫完成回調(diào)

實(shí)現(xiàn)實(shí)例:小飛機(jī)降落

1、添加一張飛機(jī)場背景圖,添加一張小飛機(jī)圖
2、為小飛機(jī)添加關(guān)鍵幀動(dòng)畫

func addKeyframes() {
   
   UIView.animateKeyframes(withDuration: 2, delay: 0, options: .calculationModeCubic, animations: {
       
       UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1/2, animations: {
           
           self.imageViewPlane.frame = CGRect(x: kScreenW-50, y: 300, width: 30, height: 30)
       })
       
       UIView.addKeyframe(withRelativeStartTime: 1/2, relativeDuration: 1/2, animations: {
           self.imageViewPlane.frame = CGRect(x: kScreenW-100, y: 300, width: 100, height: 100)
       })
       
   }) { (finish) in
       
   }
}

常見的效果有下面幾類:

// 運(yùn)算模式:連續(xù)
public static var calculationModeLinear: UIView.KeyframeAnimationOptions { get } // default
// 運(yùn)算模式:離散
public static var calculationModeDiscrete: UIView.KeyframeAnimationOptions { get }
// 運(yùn)算模式:均勻執(zhí)行
public static var calculationModePaced: UIView.KeyframeAnimationOptions { get }
// 運(yùn)算模式:平滑
public static var calculationModeCubic: UIView.KeyframeAnimationOptions { get }
// 運(yùn)算模式:平滑均勻
public static var calculationModeCubicPaced: UIView.KeyframeAnimationOptions { get }

添加關(guān)鍵幀方法:addKeyframe()

@available(iOS 7.0, *)
open class func addKeyframe(withRelativeStartTime frameStartTime: Double, relativeDuration frameDuration: Double, animations: @escaping () -> Void)

這個(gè)方法描述了在什么位置添加一個(gè)持續(xù)時(shí)間多長的關(guān)鍵幀。改方法的幾個(gè)參數(shù)如下:

withRelativeStartTime   // 關(guān)鍵幀起始時(shí)間
relativeDuration        // 關(guān)鍵幀相對(duì)持續(xù)時(shí)間
animations              // 關(guān)鍵幀具體實(shí)現(xiàn)內(nèi)容

示例:


關(guān)鍵幀動(dòng)畫示例.gif

逐幀動(dòng)畫

逐幀動(dòng)畫實(shí)現(xiàn)的動(dòng)畫效果就是將圖片一幀幀的逐幀渲染。這里準(zhǔn)備了飛機(jī)飛行過程中67張靜態(tài)圖片。

基于NSTimer的逐幀動(dòng)畫效果

class ZhuZhenVC: UIViewController {
    
    var imageView:UIImageView?
    var timer:Timer?
    var index = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()

        imageView = UIImageView(frame: UIScreen.main.bounds)
        imageView?.contentMode = UIView.ContentMode.scaleAspectFit
        index = 0
        self.view.addSubview(self.imageView!)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.refushImage), userInfo: nil, repeats: true)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        timer?.invalidate()
    }
    
    @objc func refushImage() {
        imageView?.image = UIImage(named: "\(index).png")
        index += 1
        if index == 67 {
            timer?.invalidate()
            index = 0
            imageView?.image = UIImage(named: "\(index).png")
        }
    }
}

基于CADisplayLink的逐幀動(dòng)畫效果

CADisplayLink 和 NSTimer有什么區(qū)別呢?
iOS設(shè)備的屏幕刷新頻率默認(rèn)是60Hz,而CADisplayLink可以保持和屏幕刷新率相同的頻率將內(nèi)容渲染到屏幕上,因此它的精度非常高。
CADisplayLink使用的時(shí)候需要注冊(cè)到 runloop中,每當(dāng)刷幀頻率到達(dá)的時(shí)候runloop就會(huì)向CADisplayLink指定的target發(fā)送一次指定的selector消息,相應(yīng)的selector中的方法會(huì)被調(diào)用一次。

var displayLink:CADisplayLink?

override func viewWillAppear(_ animated: Bool) {
   super.viewWillAppear(animated)
   
   displayLink = CADisplayLink(target: self, selector: #selector(refushImage))
   displayLink?.preferredFramesPerSecond = 1
   displayLink?.add(to: RunLoop.current, forMode: .default)
}

示例


104.gif

基于draw方法的逐幀動(dòng)畫效果

當(dāng)創(chuàng)建一個(gè)新的view時(shí),其自動(dòng)生成一個(gè)draw()方法,且此方法可以被重寫,一旦draw()被調(diào)用,Cocoa就會(huì)為我們創(chuàng)建一個(gè)圖形上下文,在圖形上下文的所有操作最終都會(huì)反映在當(dāng)前的UIView界面上。按照這個(gè)思路,如果定期調(diào)用draw()方法繪制新的內(nèi)容,就可以實(shí)現(xiàn)逐幀動(dòng)畫效果。

總結(jié)draw()觸發(fā)的機(jī)制:
(1)使用addSubview會(huì)觸發(fā)layoutSubviews
(2)使用viewframe屬性會(huì)觸發(fā)layoutSubviews(frame更新)
(3)直接調(diào)用layoutSubviews方法會(huì)觸發(fā)layoutSubviews

新建一個(gè)UIview類:

class BlackHoleView: UIView {

    var blackHoleRadius:Float = 0
    
    func blackHoleIncrease(_ radius:Float) {
        blackHoleRadius = radius
        // 調(diào)用setNeedsDisplay()方法實(shí)現(xiàn)draw()方法的調(diào)用
        self.setNeedsDisplay()
    }
    
    override func draw(_ rect: CGRect) {
        // Drawing code
        
        let ctx = UIGraphicsGetCurrentContext()!
        ctx.addArc(center: CGPoint(x: self.center.x, y: self.center.y),
                   radius: CGFloat(blackHoleRadius),
                   startAngle: 0,
                   endAngle: .pi*2,
                   clockwise: false)
        /*
         public func addArc(center: CGPoint,    // 當(dāng)前繪制圓形中心點(diǎn)的x,y坐標(biāo)
                            radius: CGFloat,    // 當(dāng)前繪制圓形半徑
                            startAngle: CGFloat,// 當(dāng)前繪制圓形開始角度
                            endAngle: CGFloat,  // 結(jié)束角度
                            clockwise: Bool)    // true順時(shí)針繪制 false逆時(shí)針繪制
         */
        
        ctx.fillPath()
    }
}

在viewController里面的實(shí)現(xiàn)代碼:

var index = 0    
var blackHole:BlackHoleView?
    
override func viewDidLoad() {
   super.viewDidLoad()
   
   blackHole = BlackHoleView()
   blackHole?.frame = UIScreen.main.bounds
   blackHole?.backgroundColor = UIColor.cyan
   self.view.addSubview(blackHole!)
   timer = Timer.scheduledTimer(timeInterval: 1.0/10, target: self, selector: #selector(self.refushImage), userInfo:nil, repeats: true)
}
        
@objc func refushImage() {
   blackHole?.blackHoleIncrease(Float(index))
   index += 1
   
   if index == 30 {
       index = 0
   }
}

示例:


重寫draw()方法的逐幀動(dòng)畫示例.gif

GIF動(dòng)畫效果

GIF 在iOS中的使用場景有以下三個(gè)方面
(1)GIF圖片分解為單幀圖片
(2)一系列單幀圖片合成GIF圖片
(3)iOS系統(tǒng)上展示GIF動(dòng)畫效果

(1)GIF圖片分解為單幀圖片

#關(guān)鍵過程 GIF - NSData - ImageIO - UIImage - Jpg/Png

整個(gè)過程劃分為5個(gè)模塊、4個(gè)過程,分別如下
(1)本地讀取GIF圖片,將其轉(zhuǎn)換為NSData數(shù)據(jù)類型
(2)將NSData作為ImageIO模塊的輸入
(3)獲取ImageIO的輸出數(shù)據(jù):UIImage
(4)將獲取到的UIImage數(shù)據(jù)存儲(chǔ)為JPG或PNG格式保存到本地

整個(gè)GIF圖片分解的過程中,ImageIO是處理過程的核心部分。它負(fù)責(zé)對(duì)GIF文件格式進(jìn)行分解,并將解析之后的數(shù)據(jù)轉(zhuǎn)換為一幀幀圖片輸出。我們不去深究GIF分解合成算法的具體實(shí)現(xiàn),掌握如何使用它就OK。

func fenJieGIF() {
   // (1)本地讀取GIF圖片,將其轉(zhuǎn)換為NSData數(shù)據(jù)類型
   let gifPath = Bundle.main.path(forResource: "plane", ofType: "gif")!
   let gifData = try! Data(contentsOf: URL(fileURLWithPath: gifPath))
   // (2)將NSData作為ImageIO模塊的輸入,遍歷所有GIF子幀
   let gifDataSource:CGImageSource = CGImageSourceCreateWithData(gifData as CFData, nil)!
   let gifImageCount:Int = CGImageSourceGetCount(gifDataSource)
   
   for i in 0...gifImageCount-1 {
       // CGImageSourceCreateImageAtIndex 返回GIF中某一幀圖像的CGImage類型數(shù)據(jù)
       let imageref = CGImageSourceCreateImageAtIndex(gifDataSource, i, nil)
       // UIImage 類方法,實(shí)例化UIImage實(shí)例對(duì)象
       let image = UIImage(cgImage: imageref!, scale: UIScreen.main.scale, orientation: UIImage.Orientation.up)
       let imageData:Data = image.pngData()!
       var docs = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
       let documentsDirectory = docs[0] as String
       let imagePath = documentsDirectory + "/\(i)" + ".png"
       try? imageData.write(to: URL(fileURLWithPath: imagePath), options: .atomic)
       print("\(imagePath)")
   }
}

最終分解.gif圖片的每幀圖片可根據(jù)打印出的路徑去查看。

(2)一系列單幀圖片合成GIF圖片

GIF合成分三部分:
(1)加載待處理的序列原始數(shù)據(jù)源
(2)在Document目錄下構(gòu)建GIF文件
(3)設(shè)置GIF文件屬性,利用ImageIO編碼GIF文件

func heChengGIF() {
   // Part1:讀取67張圖片
   let images:NSMutableArray = NSMutableArray()
   for i in 0...66 {
       let imagePath = "\(i).png"
       let image:UIImage = UIImage(named: imagePath)!
       images.add(image)
   }
   
   // Part2:在Document目錄下創(chuàng)建gif文件
   var docs = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
   let documentsDirectory = docs[0] as String
   let gifPath = documentsDirectory + "/plane.gif"
   print(gifPath)
   // 文件路徑由string類型轉(zhuǎn)換為URL類型
   let url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, gifPath as CFString, CFURLPathStyle.cfurlposixPathStyle, false)
   let destion = CGImageDestinationCreateWithURL(url!, kUTTypeGIF, images.count, nil)
   /*
    CGImageDestinationCreateWithURL()
    方法的作用是創(chuàng)建一個(gè)圖片的目標(biāo)對(duì)象,這里方便理解可以把圖片目標(biāo)對(duì)象比喻為一個(gè)集合體,
    集合體中描述了當(dāng)前圖片目標(biāo)對(duì)象的一系列參數(shù),如圖片的URL地址、圖片類型、圖片幀數(shù)、配置參數(shù)等
    */
   
   // Part3:設(shè)置gif圖片屬性,利用67張png圖片構(gòu)建gif
   let cgimagePropertiesDic = [kCGImagePropertyGIFDelayTime as String:0.1]//設(shè)置每幀之間播放時(shí)間
   let cgimagePropertiesDestDic = [kCGImagePropertyGIFDictionary as String:cgimagePropertiesDic];
   for cgimage in images{
       CGImageDestinationAddImage(destion!, (cgimage as AnyObject).cgImage!!,cgimagePropertiesDestDic as CFDictionary?);
   }// 依次為gif圖像對(duì)象添加每一幀元素
   
   let gifPropertiesDic:NSMutableDictionary = NSMutableDictionary()
   gifPropertiesDic.setValue(kCGImagePropertyColorModelRGB, forKey: kCGImagePropertyColorModel as String)// 設(shè)置圖像的彩色空間格式
   gifPropertiesDic.setValue(16, forKey: kCGImagePropertyDepth as String)// 設(shè)置圖像的顏色深度
   gifPropertiesDic.setValue(1, forKey: kCGImagePropertyGIFLoopCount as String)// 設(shè)置Gif執(zhí)行次數(shù)
   let gifDictionaryDestDic = [kCGImagePropertyGIFDictionary as String:gifPropertiesDic]
   CGImageDestinationSetProperties(destion!,gifDictionaryDestDic as CFDictionary?);//為gif圖像設(shè)置屬性
   CGImageDestinationFinalize(destion!);
}

CGImageDestinationCreateWithURL()
方法的作用是創(chuàng)建一個(gè)圖片的目標(biāo)對(duì)象,這里方便理解可以把圖片目標(biāo)對(duì)象比喻為一個(gè)集合體,
集合體中描述了當(dāng)前圖片目標(biāo)對(duì)象的一系列參數(shù),如圖片的URL地址、圖片類型、圖片幀數(shù)、配置參數(shù)等。

本示例中,將plane.gif的本地文件路徑作為參數(shù)1傳遞給這個(gè)圖片目標(biāo)對(duì)象,參數(shù)2描述了圖片類型為GIF圖片(需要引入框架 import MobileCoreServices),參數(shù)3表明當(dāng)前GIF圖片構(gòu)成的幀數(shù),參數(shù)4暫時(shí)給空值。

CGImageDestination.png

最終合成的.gif圖片可根據(jù)打印出的路徑去查看。

(3)iOS系統(tǒng)上展示GIF動(dòng)畫效果

iOS原生不支持直接顯示GIF圖片,故:
(1)先分解GIF圖片為單幀圖片
(2)再展示多幀圖片

func zhanShiGIF() {
   /*
    iOS原生不支持直接顯示GIF圖片,故:
    (1)先分解GIF圖片為單幀圖片
    (2)再展示多幀圖片
    */
   
   var images:[UIImage] = []
   for i in 0...66 {
       let imagePath = "\(i).png"
       let image:UIImage = UIImage(named: imagePath)!
       images.append(image)
   }
   
   let imageView = UIImageView(frame: self.view.bounds)
   imageView.contentMode = UIView.ContentMode.center
   self.view.addSubview(imageView)
   imageView.animationImages = images
   imageView.animationDuration = 5
   imageView.animationRepeatCount = 1
   imageView.startAnimating()
}

如果您有興趣的話
上一節(jié)《iOS動(dòng)畫》讀書筆記·前序
下一節(jié)《iOS動(dòng)畫》讀書筆記·內(nèi)容層動(dòng)畫

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

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

  • 1 CALayer IOS SDK詳解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi閱讀 5,331評(píng)論 3 23
  • 在iOS實(shí)際開發(fā)中常用的動(dòng)畫無非是以下四種:UIView動(dòng)畫,核心動(dòng)畫,幀動(dòng)畫,自定義轉(zhuǎn)場動(dòng)畫。 1.UIView...
    請(qǐng)叫我周小帥閱讀 3,313評(píng)論 1 23
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜,今天將帶大家一窺iOS動(dòng)畫全貌。在這里你可以看...
    F麥子閱讀 5,262評(píng)論 5 13
  • 書寫的很好,翻譯的也棒!感謝譯者,感謝感謝! iOS-Core-Animation-Advanced-Techni...
    錢噓噓閱讀 2,428評(píng)論 0 6
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,626評(píng)論 1 32

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