读“三十天三十个 Swift 项目”笔记(上)

前几天在github上有一个叫30DaysofSwift比较火,作为一直也在关注Swift这块的我,果断下载下来学习,发现确实简单实用,所以自己也跟随作者试着重写,并将每一个Demo中的一些重点记录了一下,特此也非常感谢Allen朝辉的开源精神。

另外作者在简书上也有记录,自学 iOS - 三十天三十个 Swift 项目

三十天三十个 Swift 项目
一、 计时器的简单使用(day01)

注意小数点的保留小数位,否则会出现异常。

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

当然NSTimer的基本使用也是需要OK的

  Timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("UpdateTimer"), userInfo: nil, repeats: true)
二、 字体的转换(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模式也是简单经典的。

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

首先作者使用

  addChildViewController
  didMoveToParentViewController

让第一层永远只有一个 Controller ,很多场景都是实用的

当然自定义拍照这块,需要学习了解下

// 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 对象来执行输入设备和输出设备之间的数据传递
    captureSession = AVCaptureSession()
    // 设置session 的规格
    captureSession?.sessionPreset = AVCaptureSessionPreset1920x1080
    // 输出设备的类型
    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)
        // 初始化照片输出流以及规格
        stillImageOutput = AVCaptureStillImageOutput()
        stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]
        
        if (captureSession?.canAddOutput(stillImageOutput) != nil){  
          // 加入输出流
            captureSession?.addOutput(stillImageOutput)
          // 图片预览层的输出
            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            previewLayer?.videoGravity = AVLayerVideoGravityResizeAspect
            previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.Portrait
             // View  加上 预览层
            cameraView.layer.addSublayer(previewLayer!)
            //  开始执行
            captureSession?.startRunning()
            
        }
        
        
    }
    

}
五、 CollectionView的简单实用 (day05)

此处用的是IB 设置CollectionView,以前设置那个 UICollectionViewFlowLayout的地方就在这里啦

size大小的设置

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

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

七、简单刷新 (day07)

这个Demo是作者用UITableViewControllerUIRefreshControl实现刷新的

// 核心代码
 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 实现的

 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,它是用来生成两种或更多颜色平滑渐变的。

整个流程:通过定时改变背景颜色,并在上面添加一个预览颜色层。

// 随机改变背景颜色

    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)

// 制作预览层

    let gradientLayer = CAGradientLayer()
    // 先设置的大小
    gradientLayer.frame = self.view.frame
    // 设置五个不同的颜色
    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]
    // 设置开始点 和 结束点
    gradientLayer.startPoint = CGPointMake(0, 0)
    gradientLayer.endPoint = CGPointMake(1, 1)
    // 添加到上面
    self.view.layer.addSublayer(gradientLayer)
九、放大缩小图片(day09)

之前我的第一反应是用UIPinchGestureRecognizer,但是缩放出来的效果不怎么好,还是按作者的思路,UIScrollerView添加UIImageView,通过UIScrollerView的代理来解决。

此时要注意ScrollView的以下几个属性和代理方法:

// 视图在scrollView中的位置(UIEdgeInsetsZero)  也相当于设置内边距
public var contentInset: UIEdgeInsets
// 设置缩放系数
public var minimumZoomScale: CGFloat 
public var maximumZoomScale: CGFloat

   // 返回将要缩放的UIView对象。要执行多次
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
}

// 当scrollView缩放时,调用该方法。在缩放过程中,回多次调用
func scrollViewDidZoom(scrollView: UIScrollView) {
}
十、 登录界面后带有视频播放,唯美效果(day10)

这个主要是对于视频播放的一个优化,其中这里面作者引用的两个类很有参考价值。

十一、渐变颜色的TableView (day11)

注意tableView中某个代理的使用

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

同事继续使用CAGradientLayer,让其cell有凸出的感觉

十二、登录的动画效果 (day12)

注意这两个基本的动画效果,以及调整 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,数值越小「弹簧」的振动效果越明显。
  • velocity: initialSpringVelocity则表示初始的速度,数值越大一开始移动越快。
  • options: 自然是动画效果啦,看我们自己选择吧

详细可以看这篇使用 iOS 8 Spring Animation API 创建动画

十三、cell的逐渐出现的动画效果 (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)

以及随机数arc4random()的使用

通过arc4random()获取0到x-1之间的整数的代码如下
let value = (Int)arc4random()%x;
获取1到x之间的整数的代码如下
let  value = (Int)(arc4random()%x )+1

十五: Twitter进入动画的模仿 (day15)

我们得大致了解下CAKeyframeAnimation, keyframe顾名思义就是关键点的frame,你可以通过设定CALayer的始点、中间关键点、终点的frame,时间,动画会沿你设定的轨迹进行移动。以及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
    // 持续的时间
    keyFrameAnimation.duration = 0.6
    // 开始的时间
    keyFrameAnimation.beginTime = CACurrentMediaTime() + 0.5
    // 这个属性用以指定时间函数,类似于运动的加速度,有以下几种类型
    /*
    
    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属性指明整个动画过程中的关键帧点,例如下面"initalBounds, secondBounds, finalBounds通过values指定的。需要注意的是,起点必须作为values的第一个值
    keyFrameAnimation.values = [initalBounds, secondBounds, finalBounds]
    // 该属性是一个数组,用以指定每个子路径(initalBounds, secondBounds, finalBounds)的时间
    keyFrameAnimation.keyTimes = [0, 0.3, 1]
    // 最后是看将其此效果放在哪里
    self.mask!.addAnimation(keyFrameAnimation, forKey: "bounds")

总的来说,动画这块需要继续学习,暂时好多地方还不太熟。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,609评论 4 59
  • 谁在用第一原则思想? 苹果公司最早向公众发起了“Think Different”的运动,而Elon Mask则在近...
    学习就是这么简单阅读 1,752评论 0 0
  • 笑,我们总在笑 赤着脚 不停地在海边奔跑 笑,我们总在笑 那无人的街角 留过你灿烂的微笑 笑,我们总在笑 谁说幸福...
    诗一般的夕阳阅读 200评论 0 1
  • 我是李解放,今年27岁,是某四线城市一名政府公务员。
    奶酪说阅读 468评论 0 2
  • 《皮囊》这本书第一句打动到我,是蔡崇达老师在形容阿太的个性时,他写“阿太是个很狠的人,连切菜都要像切排骨那样用力”...
    我是踢踢啦阅读 938评论 6 8