Stanford CS193p iOS开发课程笔记(七)

2015年12月10日

Stanford CS193p第八课 View Controller Lifecycle, Autolayout

View Controller Lifecycle

  • View Controller Lifecycle是什么
    即一系列发送至View Controller消息的生命周期

  • 为什么要关心View Controller Lifecycle
    通常我们会在项目的子类中腹泻这些发送给View Controller 的消息,来了解我们的应用正在干什么.
    我们可能希望做一些决定或其他操作在View Controller 生命周期的某一个特定时刻

  • View Controller Lifecycle如何工作
    1.从StoryBoard中得到实例化
    2.得到awakeFromNib
    3.segue准备发生
    4.outlets将被系统设置
    5.viewDidLoad方法将被调用
    6.View将会出现并且消失(viewWillAppear,ViewDidAppear,viewWillDisappear,viewDidDisappear)
    7.随着视图控制器的几何变化(屏幕翻转)viewWillLayoutSubview方法被调用,然后是viewDidLayoutSubview.这也许会发生很多次
    8.如果可用内存很小,可能会得到内存警报(didReceiveMemoryWarning)

  • viewDidLoad
    在viewDidLoad中初始化视图代码是最好的方式,因为在viewDidLoad进行加载前,segue已经准备完毕、outlets的设定已经完成.不要忘记调用super. viewDidLoad
    通常我们在viewDidLoad中做的是更新UI,一旦我们的Model发生了改变,我们的Model会在属性观察器中更新UI.所以最好在viewDidLoad中进行UI更新

  • 注意:不要在viewDidLoad中做与几何位置相关的操作.

Autolayout

  • Autolayout主要是通过StoryBoard来进行实现, Autolayout还是要在自己不断的使用和调试中积累经验,在此不做过多的叙述.

  • AutolayoutDemo
    本课跟随教程实现了一个小登录器的项目,主要是调试登录后图片的自动布局及旋转后的布局,大多数布局由StoryBoard上的操作完成,图片的自动布局有代码来完成.DEMO的代码如下

//viewController
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var LogingField: UITextField!

    @IBOutlet weak var passwordField: UITextField!

    @IBOutlet weak var passwordLabel: UILabel!
    
    @IBOutlet weak var nameLabel: UILabel!
    
    @IBOutlet weak var companyLabel: UILabel!
    
    @IBOutlet weak var imageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        updateUI()
    }
    
    var secure = false {
        didSet {
            updateUI()
        }
    }
    
    var loggedInUser: User? {
        didSet {
            updateUI()
        }
    }
    
    private func updateUI() {
        passwordField.secureTextEntry = secure //设置密码框的加密输入,为true时密码被替换为***,为false时直接显示输入值
        passwordLabel.text = secure ? "secured Password" : "Password"
        nameLabel.text = loggedInUser?.name
        companyLabel.text = loggedInUser?.company
        image = loggedInUser?.image
    }
    
    @IBAction func toggleSecurity(sender: UIButton) { //改变密码显示方式
        secure = !secure
    }
    

    @IBAction func login() {
        loggedInUser = User.login(LogingField.text ?? "", password: passwordField.text ?? "")
    }
    
    var image: UIImage? {
        get {
            return imageView.image
        }
        set {
            imageView.image = newValue
            if let constrainedView = imageView {
                if let newImage = newValue { //设置约束
                    aspectRatioConstraint = NSLayoutConstraint(item: constrainedView, attribute: .Width, relatedBy: .Equal, toItem: constrainedView, attribute: .Height, multiplier: newImage.aspectRatio, constant:0)
                }else {
                    aspectRatioConstraint = nil
                }
            }
        }
    }
    
    
    //NSLayoutConstraint为所有约束的class
    var aspectRatioConstraint: NSLayoutConstraint? {
        willSet { //在未设置前清除已存在的约束
            if let existingConstraint = aspectRatioConstraint {
                view.removeConstraint(existingConstraint)
            }
        }
        didSet { //设置约束
            if let newConstraint = aspectRatioConstraint {
                view.addConstraint(newConstraint)
            }
        }
    }

}

//对Model进行扩展,添加image
extension User {
    var image: UIImage? {
        if let image = UIImage(named: login) {
              return image
        } else {
            return UIImage(named: "unknown_user")
        }

    }
}

//保证图片宽高比与原图一致
extension UIImage {
    var aspectRatio: CGFloat {
        return size.height != 0 ? size.width / size.height : 0
    }
}


//Model
import Foundation

struct User {
    let name: String
    let company: String
    let login: String
    let password: String
    
    static func login(login: String, password: String) -> User? {
        if let user = datebase[login] {
            if user.password == password {
                return user
            }
        }
        return nil
    }
    //数据库
    static let datebase: Dictionary = {
        var theDatabase = Dictionary()
        for user in [
            User(name: "John Appleseed", company: "Apple", login: "japple", password: "foo"),
            User(name: "Madisom Bumgarner", company: "World Champion San Francisco Giants", login: "madbum", password: "foo"),
            User(name: "John Hennessy", company: "Stanford", login: "hennessy", password: "foo"),
            User(name: "Bad Guy", company: "Criminals Inc", login: "baddie", password: "foo")
            ] {
                theDatabase[user.login] = user
        }
        return theDatabase
    }()
    
}

你可能感兴趣的:(Stanford CS193p iOS开发课程笔记(七))