斯坦福大学swift课程笔记

2017-02-17 12:34

接到任务需要将Chromecast的iOS sender给实现一下,但是iOS基础太薄弱了,进行了一段时间感觉困难重重,需要系统得学习一下基础知识。所以在youtube上看了一下斯坦福大学的iOS教学视频,那位老师讲得非常棒,为了避免遗忘,记一下听课的笔记。

Lecture 5

View的更新

  • 在View上面添加@IBDesignable可以在storyboard中看到效果。
  • 在变量上面添加 @IBInspectabl可以在storyboard中改变这些变量值,查看改变后的变化效果。运行的时候回应用改变的值。
  • 当改变一个变量的值需要UI重绘的时候可以使用didSet:

    var scale: CGFLoat = 0.90 {
        didSet{
            setNeedsDisPlay()
        }
    }
    
  • 按住Ctrl拖动view到ViewControler来创建一个View的实例对象

  • 对于可选变量,使用的时候可以在后面加上默认值
    var value = optionalVaule ?? 0
    

手势

  • 手势由UIGestureRecognizer的子类来识别。
  • 添加一个gesture recognizer到UIVIew并且提供一个handle方法来处理手势。

    @IBOutLet weak var pannableView: UIView{
        dieset{
            let recognizer = UIPanGestureRecongnizer(
            //self 代表手势的接收者,(_:)表示方法有个参数
            target: self, action: #selector(ViewController.pan(_:))
            )
        pannableView.addGestureReconginzer(recognizer)
        }
    }
    
  • UIGestureRecognizer包含了一个状态信息:

    var state: UIGestureRecognizerState {get}
    
    • 其初始值为.Possible
    • 当有离散手势(如点击)时,变为.Recognized
    • 当有连续手势时,先是变成.Began, 然后是重复的.Changed, 最后是.Ended。
    • 可能有.Failed或者.Cancelled
  • 处理pan手势的handler方法:

    func pan(gesture: UIPangestureRecognizer) {
        switch getsture.state {
            case .Changed: fallthrough
            case .Ended:
                let translation = getsture.translationInView(pannableView)
                //do some update
                gesture.setTranslation(CGPoint
                Zero, inView: pannableView)
            default: break
        }
    }
    
  • 识别手势的类有:

    UIPinchGestureRecognizer
        var scale: CGFloat
        var velocity: CGFloat {get}
    
    UIRotationGestureRecognizer
        var rotation: CGFloat
        var velocity: CGFloat {get}
    
    UISwipeGestureRecognizer
        // set up the direction and number of fingers you want, then look for .Recongnized
        var direction: UISwipeGestureRecognizerDirection
        var numberOfTouchesRequired: Int
    
    UITapGestureRecognizer
        // set up number of taps and fingers you want, then look for  .Ended
        var numberOfTapsRequired: Int
        var numberOfTouchesRequired: Int
    

组合MVC

  • UISplitViewController: 讲两个MVC并列放在一起
  • UINavigationController: 就是一个MVC的栈

Lecture 6

Segues

  • 一个MVC启动另外一个MVC叫做Segue,Segue总会创建新的MVC实例。
  • 每个Segue都有个id, 在代码中用来识别不同的Segue.
  • Segue中包含源storyboad的id和目标MVC的controller

    func preparedForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
        if let identifier = segue.identifier {
            switch identifier {
                case "show graph":
                    if let vc = segue.destinationViewController as? GraphController {
                        vc .property1 = ..
                        vc.callMethodToSetItUp(...)
                    }
                default: break
            }
        }
    }
    
  • 在代码里发送segue

    performSegueWithIdentifier(segue, sender: view)
    
  • 使用字典来代替switch

  • SplitViewController只能正常工作在iPad或者iPhone6S这种大屏设备上。要在手机上正常工作,需要选择Editor->Embed In->Navigation Controller

    View Controller Lifecycle

  • viewDidLoad: View 实例化后调用,可以做一些初始化操作,如根据Model来更新UI,比init方法更好,因为调用的时候outlets都会被准备好了。但是view的大小还没确定。类似于Android里面的onCreate.
  • viewWillAppear: view将要在屏幕上显示的时候调用,所以会被多次调用,类似于Android里面的onStart.
  • viewDidAppear: View 已经可见了,可以开始动画。类似于Android里面的onResume
  • viewWillDisappear: view 将不可见,保存状态。类似于Android中的onPause.
  • viewDidDisappear: view已经不可见了,类似Android中的onStop
  • viewWillLayoutSubviews
  • viewDidLayoutSubviews: 当一个view的frame发生改变,或者它的子view重新布局的时候被调用
  • viewWillTransitionToSize: 横竖屏改变的时候调用

    Lecture 7

    Memory Management

    引用类型都是存储在堆里,系统会自动对实例对象进行计数,当计数为0的时候就会回收。引用的类型包括:
  • strong: 指向的对象会一直保留在堆中。
  • weak: 如果没有别的引用指向这个对象,那就设置为nil. 只能是可选类型
  • unowned: 不要对其进行引用计数,有错误的时候直接crash

closure

会因为循环调用使内存无法释放,解决方式:

brain.addOperation("Z") { [ weak weakSelf = self ] in
    weakSelf?.display.textColor = UIColor.redColor()
    return sqrt($0)
}

当对象要从堆里被清 除的时候,deinit方法会被调用

Extensions

Extensions 可以让我们添加新方法、属性到一个class/struct/enum,无论有没有源码。

Protocols

一系列方法和属性的声明,类似于java中的接口

Delegation

View和Controller之间进行通信的方法,使用protocols实现。

图片加载

let url = NSURL(string: stringUrl)
if let imageData = NSData(contentsOfURL: url){
    image = UIImage(data: imageData)
    }

Lecture 8

扩展UINavigationController

extension UIViewController {
    var contentViewConttroller: UIViewController {
        if let navcon = self as? UINavigationController {
            return navcon.visibleViewController ?? self
        } else {
        return self

多线程

同Android一样,有一个更新UI的主线程,其它耗时任务放在其它线程里进行。

开一个新线程

let queue: dispatch_queue_t = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
dispatch_async(quese){
    //do something
}

使用主线程

let mainQ: dispatch_queue_t = dispatch_get_main_queue()
dispatch_async(not the main queue) {
    //do a non-UI jos
    dispatch_async(dispatch_get_main_queue){
        //call UI functions
    }
}

代码创建segue

performSegueWithIdentifier(Storyboard.ShowInamge, sender:sender)

Lecture 9

UITableVIew

同Android里的listview

调整每个item的高度自适应

tableView.estimatedRowHeight = tableVie.rowHeight
tableView.rowHeight = UITableViewAUtomaticDimension

Lecture 12

Auto layout

  • 只有iPad的原始尺寸的大小,其他的都有压缩

    Lecture 13

NSTimer

  • 只能在主线程中使用
    let timer-NStimer.scheduledTimeWithTimeInterval(2.0,
        target: self,
        selector: #selector(fire(_:)),
        userInfo: nil,
        repeats: true
    
    func fire(time: NSTimer) {
        // do something
    }
    

Animation

Animation 种类

  • Animating UIView properties - 变更边界和透明度

  • Animation of View Controller transitions

  • Core Animation
  • OpenGL -3D
  • SpriteKit - 2.5D
  • Dynamic Animation

Lecture 15

NSNotification

同Androd里的broadcast

注册

let center =NSNotificationCenter.defaultCenter()
var observer = center. addObserverForName(UIContentSizeCategoryDidChangeNotification,
    Object: UIApplication.sharedApplication(),
    queue: NSOperationQueue.mainQueue())
{
notification in
// do somethinf
let c = notification.userInfo?[UIContentSizeCategoryNewValueKey】
}
center.removeObserver(observer)

发送

let notification = NSNotification(
    name:String,
    object: AnyObject?,
    userInfo:Dictinary
)
NSNotificationCenter.defaultCenter().postNofification(notification)

Alert

  • 在屏幕中间弹出
  • 一般就一两个选项如ok,cancel
  • 打断用户交互,慎重使用
  • 经常用来处理同步的问题,如网络中断等
  • 可以有个text field来接收用户输入

Action Sheets

  • 从底部滑入
  • 可以从 bar button item 或者其它矩形区域展现
  • 一般询问杜宇两个回答的问题
  • 可以理解为给用户一堆选择
var alert = UIAlertController(
    title: "redeploy Cassini",
    message: "message",
    preferredStyle: UIAlertControllerStyle.ActionSheet// .Alert
))
alert.addAction(UIAlertAction(
title: "title",
//style: .Destruction)// 红色显示
//style: .Cancel
style, UIAlertActionStyle.Default){
(action:UIAlertAction) -> Void in
    //go to somewhere
}

presentViewController(alert, animated: true, completioon: nil)

Lecture 17

Dismiss a view controller

func dismissViewControllerAnimated(Bool, completion: () -> Voie)