讀“三十天三十個 Swift 項目”筆記(上)

前幾天在github上有一個叫30DaysofSwift比較火,作為一直也在關(guān)注Swift這塊的我,果斷下載下來學(xué)習(xí),發(fā)現(xiàn)確實簡單實用,所以自己也跟隨作者試著重寫,并將每一個Demo中的一些重點記錄了一下,特此也非常感謝Allen朝輝的開源精神。

另外作者在簡書上也有記錄,自學(xué) iOS - 三十天三十個 Swift 項目

三十天三十個 Swift 項目
一、 計時器的簡單使用(day01)

注意小數(shù)點的保留小數(shù)位,否則會出現(xiàn)異常。

  timeLabel.text = String(format: "%.1f", Counter)

當(dāng)然NSTimer的基本使用也是需要OK的

  Timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("UpdateTimer"), userInfo: nil, repeats: true)
二、 字體的轉(zhuǎn)換(day02)

了解 常用的字體

   for family in UIFont.familyNames() {
        for font in UIFont.fontNamesForFamilyName(family){
            print(font)
        }
   }

然后通過這方法使用就OK了

 public /*not inherited*/ init?(name fontName: String, size fontSize: CGFloat)
三、 TableView點擊詳情播放視頻(day03)

我覺的其中播放視頻這塊,路徑別寫錯了

  let path = NSBundle.mainBundle().pathForResource("emoji zone", ofType: "mp4")
  playerView = AVPlayer(URL: NSURL(fileURLWithPath: path!))
  playViewController.player = playerView
  self.presentViewController(playViewController, animated: true) {
        self.playViewController.player?.play()
  }

另外作者用MVC模式也是簡單經(jīng)典的。

四、 ScrollerView + 自定義拍照(day04)

首先作者使用

  addChildViewController
  didMoveToParentViewController

讓第一層永遠只有一個 Controller ,很多場景都是實用的

當(dāng)然自定義拍照這塊,需要學(xué)習(xí)了解下

// MARK:- 屬性
var captureSession : AVCaptureSession?
var stillImageOutput : AVCaptureStillImageOutput?
var previewLayer : AVCaptureVideoPreviewLayer?
@IBOutlet var cameraView: UIView!


//MARK:- CilcleLife
override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    previewLayer?.frame = cameraView.bounds
}

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    // 初始化 session 對象來執(zhí)行輸入設(shè)備和輸出設(shè)備之間的數(shù)據(jù)傳遞
    captureSession = AVCaptureSession()
    // 設(shè)置session 的規(guī)格
    captureSession?.sessionPreset = AVCaptureSessionPreset1920x1080
    // 輸出設(shè)備的類型
    let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    var error : NSError?
    // 輸入流
    var input: AVCaptureDeviceInput!
    
    do {
        input = try AVCaptureDeviceInput(device: backCamera)
    } catch let error1 as NSError {
        error = error1
        input = nil
    }
    
    if (error == nil && captureSession?.canAddInput(input) != nil){
        // 加入輸入流
        captureSession?.addInput(input)
        // 初始化照片輸出流以及規(guī)格
        stillImageOutput = AVCaptureStillImageOutput()
        stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]
        
        if (captureSession?.canAddOutput(stillImageOutput) != nil){  
          // 加入輸出流
            captureSession?.addOutput(stillImageOutput)
          // 圖片預(yù)覽層的輸出
            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            previewLayer?.videoGravity = AVLayerVideoGravityResizeAspect
            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.Portrait
             // View  加上 預(yù)覽層
            cameraView.layer.addSublayer(previewLayer!)
            //  開始執(zhí)行
            captureSession?.startRunning()
            
        }
        
        
    }
    

}
五、 CollectionView的簡單實用 (day05)

此處用的是IB 設(shè)置CollectionView,以前設(shè)置那個 UICollectionViewFlowLayout的地方就在這里啦

size大小的設(shè)置

六、地理位置的確定(day06)

一定要記住iOS8之后,一定要在infoPlist 中加入
NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription 才能正常使用地理位置。

七、簡單刷新 (day07)

這個Demo是作者用UITableViewControllerUIRefreshControl實現(xiàn)刷新的

// 核心代碼
 tableViewController.refreshControl = self.refreshControl
 self.refreshControl.addTarget(self, action: "didRoadEmoji", forControlEvents: .ValueChanged)    
 self.refreshControl.backgroundColor = UIColor(red:0.113, green:0.113, blue:0.145, alpha:1)
 let attributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
 self.refreshControl.attributedTitle = NSAttributedString(string: "Last updated on \(NSDate())", attributes: attributes)
 self.refreshControl.tintColor = UIColor.whiteColor()

而我是就是簡單用UITableView + UIRefreshControl 實現(xiàn)的

 tableView.tableFooterView = UIView()
 refreshControl.addTarget(self, action: Selector("refreshTheData"), forControlEvents: UIControlEvents.ValueChanged)
  // 增加備注文字
 let attributes = [NSForegroundColorAttributeName: UIColor.grayColor()]
 refreshControl.attributedTitle = NSAttributedString(string: "上次刷新時間 \(NSDate())", attributes: attributes)
 tableView.addSubview(refreshControl)
八、隨音樂漸變背景閃效果 (day08)

首先我們需要了解下CagradientLayer,它是用來生成兩種或更多顏色平滑漸變的。

整個流程:通過定時改變背景顏色,并在上面添加一個預(yù)覽顏色層。

// 隨機改變背景顏色

    let redValue = CGFloat(drand48())
    let blueValue =  CGFloat(drand48())
    let greenValue = CGFloat(drand48())
    self.view.backgroundColor = UIColor(red: redValue, green: greenValue, blue: blueValue, alpha: 1.0)

// 制作預(yù)覽層

    let gradientLayer = CAGradientLayer()
    // 先設(shè)置的大小
    gradientLayer.frame = self.view.frame
    // 設(shè)置五個不同的顏色
    let color1 = UIColor(white: 0.5, alpha: 0.2).CGColor as CGColorRef
    let color2 = UIColor(red: 1.0, green: 0, blue: 0, alpha: 0.4).CGColor as CGColorRef
    let color3 = UIColor(red: 0, green: 1, blue: 0, alpha: 0.3).CGColor as CGColorRef
    let color4 = UIColor(red: 0, green: 0, blue: 1, alpha: 0.3).CGColor as CGColorRef
    let color5 = UIColor(white: 0.4, alpha: 0.2).CGColor as CGColorRef
    // 放入顏色層中
    gradientLayer.colors = [color1, color2, color3, color4, color5]
    // 并為這五個顏色確定 locations
    gradientLayer.locations = [@0.10, @0.30, @0.50, @0.70, @0.90]
    // 設(shè)置開始點 和 結(jié)束點
    gradientLayer.startPoint = CGPointMake(0, 0)
    gradientLayer.endPoint = CGPointMake(1, 1)
    // 添加到上面
    self.view.layer.addSublayer(gradientLayer)
九、放大縮小圖片(day09)

之前我的第一反應(yīng)是用UIPinchGestureRecognizer,但是縮放出來的效果不怎么好,還是按作者的思路,UIScrollerView添加UIImageView,通過UIScrollerView的代理來解決。

此時要注意ScrollView的以下幾個屬性和代理方法:

// 視圖在scrollView中的位置(UIEdgeInsetsZero)  也相當(dāng)于設(shè)置內(nèi)邊距
public var contentInset: UIEdgeInsets
// 設(shè)置縮放系數(shù)
public var minimumZoomScale: CGFloat 
public var maximumZoomScale: CGFloat

   // 返回將要縮放的UIView對象。要執(zhí)行多次
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
}

// 當(dāng)scrollView縮放時,調(diào)用該方法。在縮放過程中,回多次調(diào)用
func scrollViewDidZoom(scrollView: UIScrollView) {
}
十、 登錄界面后帶有視頻播放,唯美效果(day10)

這個主要是對于視頻播放的一個優(yōu)化,其中這里面作者引用的兩個類很有參考價值。

十一、漸變顏色的TableView (day11)

注意tableView中某個代理的使用

 func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)     {
}

同事繼續(xù)使用CAGradientLayer,讓其cell有凸出的感覺

十二、登錄的動畫效果 (day12)

注意這兩個基本的動畫效果,以及調(diào)整 constant 后需要 self.view.layoutIfNeeded()

UIView.animateWithDuration(0.5, delay: 0.00, options: UIViewAnimationOptions.CurveEaseOut, animations: {
        
        self.centerAlignUsername.constant += self.view.bounds.width
        self.view.layoutIfNeeded()
    
        }, completion: nil)

UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.2, initialSpringVelocity: 10, options: UIViewAnimationOptions.CurveLinear, animations: {
        
        self.loginButton.bounds = CGRect(x: bounds.origin.x - 20, y: bounds.origin.y, width: bounds.size.width + 60, height: bounds.size.height)
        
        }, completion: nil)

后者是一個橫向變寬的View彈出的動畫效果,同時我們進一步了解下這個方法,通過Oc來看,更清楚一些。

+ (void)animateWithDuration:(NSTimeInterval)duration
                  delay:(NSTimeInterval)delay
 usingSpringWithDamping:(CGFloat)dampingRatio
  initialSpringVelocity:(CGFloat)velocity
                options:(UIViewAnimationOptions)options
             animations:(void (^)(void))animations
             completion:(void (^)(BOOL finished))completion
  • dampingRatio: usingSpringWithDamping的范圍為0.0f到1.0f,數(shù)值越小「彈簧」的振動效果越明顯。
  • velocity: initialSpringVelocity則表示初始的速度,數(shù)值越大一開始移動越快。
  • options: 自然是動畫效果啦,看我們自己選擇吧

詳細可以看這篇使用 iOS 8 Spring Animation API 創(chuàng)建動畫

十三、cell的逐漸出現(xiàn)的動畫效果 (day13)

只要注意以下這個在viewWillAppear處理就OK了,以后我們的動畫cell思路確實可以這樣做。

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    
    self.tableView.reloadData()
    // 該方法是獲取界面上能顯示出來了cell
    let cells = tableView.visibleCells
    // 獲取總的高度
    let tableHeight: CGFloat = tableView.bounds.size.height
    
    // 先讓每一cell 都在下面
    for i in cells {
        let cell: UITableViewCell = i as UITableViewCell
        // 改變位置
        cell.transform = CGAffineTransformMakeTranslation(0, tableHeight)
    }
    
    var index = 0
    
    for a in cells {
        
        let cell: UITableViewCell = a as UITableViewCell
        
        UIView.animateWithDuration(1.5, delay: 0.05 * Double(index), usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
            // 回歸位置
            cell.transform = CGAffineTransformMakeTranslation(0, 0);
            
            }, completion: nil)
        
        index += 1
    }
    
}
十四、UIPickerView 的動畫選擇器效果(day14)

此處考查的可以說是UIPickerView的用法,常用的幾個代理方法以及下面這個方法:

  //主動去選擇 改變的
 public func selectRow(row: Int, inComponent component: Int, animated: Bool)

以及隨機數(shù)arc4random()的使用

通過arc4random()獲取0到x-1之間的整數(shù)的代碼如下
let value = (Int)arc4random()%x;
獲取1到x之間的整數(shù)的代碼如下
let  value = (Int)(arc4random()%x )+1

十五: Twitter進入動畫的模仿 (day15)

我們得大致了解下CAKeyframeAnimation, keyframe顧名思義就是關(guān)鍵點的frame,你可以通過設(shè)定CALayer的始點、中間關(guān)鍵點、終點的frame,時間,動畫會沿你設(shè)定的軌跡進行移動。以及C?ALayer的基本使用。

CALayer

    self.mask = CALayer()
    self.mask?.contents = UIImage(named: "twitter")?.CGImage
    // 縮放常量
    self.mask?.contentsGravity = kCAGravityResizeAspect
    // 大小
    self.mask?.bounds = CGRect(x: 0, y: 0, width: 100, height: 80)
    // 錨點
    self.mask?.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    // 位置點
    self.mask?.position = CGPoint(x: imageView.frame.size.width / 2, y: imageView.frame.size.height / 2)
    // 真正將mask 賦值給 UIImageView上的mask
    imageView.layer.mask = self.mask

CAKeyframeAnimation

    let keyFrameAnimation = CAKeyframeAnimation(keyPath: "bounds")
    keyFrameAnimation.delegate = self
    // 持續(xù)的時間
    keyFrameAnimation.duration = 0.6
    // 開始的時間
    keyFrameAnimation.beginTime = CACurrentMediaTime() + 0.5
    // 這個屬性用以指定時間函數(shù),類似于運動的加速度,有以下幾種類型
    /*
    
    1 kCAMediaTimingFunctionLinear//線性
    2 kCAMediaTimingFunctionEaseIn//淡入
    3 kCAMediaTimingFunctionEaseOut//淡出
    4 kCAMediaTimingFunctionEaseInEaseOut//淡入淡出
    5 kCAMediaTimingFunctionDefault//默認
    
    */
    keyFrameAnimation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut), CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)]
    
    // 初始化大小
    let initalBounds = NSValue(CGRect: mask!.bounds)
    // 中間的大小
    let secondBounds = NSValue(CGRect: CGRect(x: 0, y: 0, width: 90, height: 73))
    // 最后的大小
    let finalBounds = NSValue(CGRect: CGRect(x: 0, y: 0, width: 1600, height: 1300))
    // values屬性指明整個動畫過程中的關(guān)鍵幀點,例如下面"initalBounds, secondBounds, finalBounds通過values指定的。需要注意的是,起點必須作為values的第一個值
    keyFrameAnimation.values = [initalBounds, secondBounds, finalBounds]
    // 該屬性是一個數(shù)組,用以指定每個子路徑(initalBounds, secondBounds, finalBounds)的時間
    keyFrameAnimation.keyTimes = [0, 0.3, 1]
    // 最后是看將其此效果放在哪里
    self.mask!.addAnimation(keyFrameAnimation, forKey: "bounds")

總的來說,動畫這塊需要繼續(xù)學(xué)習(xí),暫時好多地方還不太熟。

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

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

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