zoukankan      html  css  js  c++  java
  • Swift培训

      本篇是Swift内部培训整理的PPT材料,主要内容来源于苹果Swift编程语言官方教程,参考了网上的一些视频课程内容。在教程介绍完之后,本人附带实现了一个项目开发中的常用场景的Demo:基于导航栏和Tab栏的应用。

    1.Swift概述

      我们先来看一篇文章:苹果新贵 Swift之前世今生

      Swift是用于设计iOS及Mac OS X应用的一门新语言。

    1.1.Swift特点

    1. Swift保留了C与Objective-C的优点,并摒弃其为了兼容C语言所受的限制;
    2. Swift吸纳了安全编程模式,并新增了一些现代化功能,使其更易使用、更为灵活、更具乐趣。
    3. Swift的简洁风格与广受欢迎的成熟框架Cocoa/Cocoa Touch相结合,将为重新构思软件的开发过程带来新机遇;
    4. Swift内存管理采用ARC风格。

    1.2.Swift代码的文件扩展名

      *.swift

    2.第一个Swift程序

    2.1.使用Xcode Project编写

    2.2.使用Playground编写

      我们可以基于 Playground 做这些事情:

    1. 学习:通过 Playground 学习 Swift,制作 Swift 教程实现交互式学习,同时还可以培训其他初学者。
    2. 代码开发:执行算法程序,迅速看到算法结果,跟踪变量;执行绘图程序,即时看到图像结果,及时调整。执行通用代码,查看变量的改变情况。
    3. 实验性代码:无需创建项目,直接打开一个独立的Playground文件即可编写代码,尝试调用新的 API。

    3.常量与变量

      let关键词声明常量,var关键词声明变量。

    let maximumNumberOfLoginAttempts = 10  // 常量只有在初始化的时候可以赋值
    
    var currentLoginAttempt = 0

    4.运算符和表达式

    4.1.运算符

    1. 算术运算符:*、/、+、—、%、++、——
    2. 关系运算符:>、<、>=、<=、==、!=
    3. 布尔逻辑运算符:!、&&、||
    4. 三元运算符:?:

    4.2.表达式

      1.不指定数据类型

    var a1 = 10
    
    var a2 = 20
    
    var a = a1 > a2 ? "a1":"a2"

      2.指定数据类型

    var a1:Int = 10
    
    var a2:Int = 20
    
    var a = a1 > a2 ? "a1":"a2"

      3.可以有分号结尾

    var a1:Int = 10; var a2:Int = 20
    
    var a = a1 > a2 ? "a1":"a2"

    4.3.注释

    //
    
    /*    */

    5.数据类型

    5.1.整型

      Swift提供8、16、32、64位形式的有符号及无符号整数,这些整数类型遵循C语言的命名规约。与Swift中的所有类型一样,这些整数类型的名称以大写字母开头

      Swift还提供了一个整数类型Int;

    1. 在32位平台,Int与Int32宽度一致;
    2. 在64位平台,Int与Int64宽度一致;

      Swift还提供了无符号整数类型UInt。

    5.2.浮点型

    1. 单精度浮点(32位) Float
    2. 双精度浮点(64位) Double

    5.3.数字型

      表示数字如下:

    let decimalInteger = 17  // 表示是10进制
    
    let binaryInteger = 0b10001  // 二进制17
    
    let octalInteger = 0o21  // 8进制17
    
    let hexadecimalInteger = 0x11  // 16进制17

    5.4.布尔类型

      true和false

    let orangesAreOrange = true
    
    let turnipsAreDelicious = false

    6.数据类型转换

    6.1.整型转换

      不同类型的整数常量或变量所能存储的值域不同,需要显示地转换

    let twoThousand:UInt16 = 2000
    
    let one:UInt8 = 1
    
    //let twoThousandAndOne = twoThousand + one  // 错误
    
    let twoThousandAndOne = twoThousand + UInt16(one)  // 正确

    6.2.整型与浮点数转换

      整数与浮点数类型之间的转换,需要显示地转换

    let three = 3
    
    let pointOneFourOneFiveNine = 0.14159
    
    let pi = Double(three) + pointOneFourOneFiveNine

    7.字符串类型

    7.1.字符串初始化

      1.初始化

    let someString = "Some string literal value"
    
    let wiseWords = ""Imagination is more important than knowledge" - Einstein"
    
    let dollarSign = "x24"  // $,Unicode scalar U+0024

      2.空值

    var emptyString = ""  // 空串初始化
    
    var anotherEmptyString = String()  // 通过初始化函数初始化

      3.空值判断

    if emptyString.isEmpty{
    
        println("Nothing to see here")
    
    }
    
    if emptyString == ""{
    
        println("Nothing to see here")
    
    }

    7.2.字符串修改

      var 声明的可以修改,let不能修改。

    var variableString = "Horse"
    
    variableString += " and carriage"

    7.3.字符串插入

      斜杠+括号+变量

    let multiplier = 3
    
    let message = "(multiplier) times 2.5 is (Double(multiplier) * 2.5)"

    7.4.字符串长度

      使用countElements函数。OC中使用length属性。

    let unusualMenagerie = "Koala , Snail, Penguin"
    
    println("unusualMenagerie has (countElements(unusualMenagerie)) characters")

    7.5.比较字符串相等

    let quotation = "We're a lot alike,you and I."
    
    let sameQuotation = "We're a lot alike,you and I."
    
    if quotation == sameQuotation{
    
        println("These two strings are considered equal")
    
    }

    8.元组(tuple)类型

      元组将多个值组合为单个值。元组内的值可以是任意类型,各元素不必是相同的类型,元组在作为函数返回值时尤其有用

      1.定义方法1

    let http404Error = (404,"Not Found")
    
    println("The status code is (http404Error.0)");
    
    println("The status message is (http404Error.1)");

      2.定义方法2

    let http200Error = (statusCode:404,discription:"Not Found")
    
    println("The status code is (http200Error.statusCode)");
    
    println("The status message is (http200Error.discription)");

    9.可选(Optional)类型

    9.1.使用可选类型

      我们在如下情况下使用可选类型:

    1. 它有值但不确定;
    2. 没有任何值。
    let possibleNumber = "123"
    
    let convertedNumber:Int?=possibleNumber.toInt()

      “Int?”是可选类型

    if convertedNumber{
    
        println("(possibleNumber) has an Integer value of (convertedNumber!)")
    
    }
    else{
    
        println("(possibleNumber) could not be convented to an integer")
    
    }

      convertedNumber是从可选类型中取值

    9.2.使用nil

      我们可以为可选类型的变量设置nil值,表示没有任何值。

    var serverResponseCode:Int?=404
    
    serverResponseCode = nil

      如果不是可选类型,那么是不能设置为nil的

    10.数组

    10.1.数组初始化

      基本语法:

    [value1,value2,value3]
    
    var shoppingList:String[] = [“Eggs","Milk"]

      对比一下OC中的方式:

    NSArray *array = @[@"aa",@"bb"];

    10.2.数组追加元素

      使用append函数追加或通过+操作符:

    var shoppingList:String[] = ["Eggs","Milk"]
    
    shoppingList.append("Flour")
    
    shoppingList += ["Cheese","Butter"]

    10.3.数组插入元素

      使用insert方法

    var shoppingList:String[] = ["Eggs","Milk"]
    
    shoppingList.insert("Butter", atIndex: 0)
    
    shoppingList += ["Cheese","Chocolate Spread"]

      比较一下OC中:

    [array insertObject:@"dd" atIndex:1];

    10.4.数组删除元素

      使用removeAtIndex方法

    var shoppingList:String[] = ["Eggs","Milk","Butter"]
    
    let deleteItem = shoppingList.removeAtIndex(2)
    
    println(deleteItem)
    
    println(shoppingList)

    10.5.数组长度

      使用count属性(和OC中一样)

    var shoppingList:String[] = ["Eggs","Milk","Butter"]
    
    println("The shopping list contains (shoppingList.count) items.")

    10.6.数组遍历

      1.遍历方法1

    var shoppingList:String[] = ["Eggs","Milk","Butter"]
    
    for item in shoppingList{
    
        println(item)
    
    }

      2.遍历方法2

      有循环变量

    for(index,value) in enumerate(shoppingList){
    
        println("Item (index + 1):(value)")
    
    }

    11.字典

    11.1.字典初始化

      基本语法:

    [key1:value1,key2:value2,key3:value3]
    
    var airports:Dictionary<String,String> = ["TYO":"Tokyo","DUB":"Dublin"]

    11.2.字典追加元素

    var airports:Dictionary<String,String> = ["TYO":"Tokyo","DUB":"Dublin"]
    
    airports["LHR"] = "Lonton"
    
    println("The dictionary of airports contains (airports.count)")

    11.3.字典删除元素

      通过removeValueForKey(key)方法删除

    var airports:Dictionary<String,String> = ["TYO":"Tokyo","DUB":"Dublin"]
    
    if let removedValue = airports.removeValueForKey("DUB"){
    
        println("The removed airport's name is (removedValue)")
    
    }
    else{
    
        println("The airports dictionary does not contains a value for DUB")
    
    }

    11.4.字典长度

      使用count属性

    println("The count of airport's is (airports.count)")

    11.5.字典遍历

      1.遍历字典

    var airports:Dictionary<String,String> = ["TYO":"Tokyo","DUB":"Dublin"]
    
    for (airportCode,airportName) in airports{
    
        println("(airportCode):(airportName)")
    
    }

      2.遍历键和值

    for airportCode in airports.keys{
    
        println("Airport code:(airportCode)")
    
    }
    
    for airportName in airports.values{
    
        println("Airport name(airportName)")
    
    }

      3.获得键和值的数组

    let airportCodes = Array(airports.keys)
    
    let airportNames = Array(airports.values)

    12.控制语句

    12.1.分支语句

      1.条件语句if-else

    if boolean-expression{
    
    statement1;
    
    }[else if boolean-expression{
    
    statement2;
    
    }]
    [else{
    
    statement3;
    
    }]

      2.多分支语句switch

    switch some value to consider{
    
    case value1,value2,value3:
    
    respond to value1
    
    default:
    
    otherwise
    
    }

      每个case不需要显示地添加break,每个case至少有一条语句。可以比较任何类型。

    12.2.循环语句

      1.while语句

    while condition{
    
    statements
    
    }

      示例:

    var i = 100
    
    var r = 0
    
    var s = 0
    
    var t = 0
    
    while i < 1000 {
    
        r = i / 100 ;
    
        s = (i - r * 100) / 10;
    
        t = i - r * 100 - s * 10;
    
        if(i == r * r * r + s * s * s + t * t * t){
    
            println("i=(i)");
    
        }
    
        i++
    
    }

      2.do-while语句

    do{
    
    statements
    
    }while condition

      示例:

    var i = 100
    
    var r = 0
    
    var s = 0
    
    var t = 0
    
    do{
    
        r = i / 100 ;
    
        s = (i - r * 100) / 10;
    
        t = i - r * 100 - s * 10;
    
        if(i == r * r * r + s * s * s + t * t * t){
    
            println("i=(i)");
    
        }
    
        i++
    
    }while i < 1000

      3.for语句

    for initialization;condition;increment{
    
    statements
    
    }

      示例:

    var i = 8
    
    var r = 0
    
    var s = 0
    
    for var j = 0;j <= i;j++ {
    
        r = j * j;
    
        s = j * j * j;
    
        println("(j)的平方:(r) (j)的立方:(s)");
    
    }

      4.for in语句

      一般用于遍历集合

      1.遍历范围

    for index in 1...5{
    
        println("(index) times 5 is (index * 5)");
    
    }

      2.忽略循环变量

    let base = 3
    
    let power = 10
    
    var answer = 1
    
    for _ in 1...power{
    
        answer *= base;
    
    }
    
    println("(base) to the power of (power) is (answer)")

      3.遍历数组

    let names = ["Anna","Alex","Jack"]
    
    for name in names{
    
        println("Hello,(name)")
    
    }

      4.遍历字典

    let numberofLegs = ["spider":8,"ant":6,"car":4];
    
    for(animalName,legCount) in numberofLegs{
    
        println("(animalName) have (legCount) legs")
    
    }

      5.遍历字符串

    for character in "Hello"{
    
        println(character)
    
    }

    12.3.跳转语句

    1. continue:终止当次循环,接着进入下一次循环
    2. break:终止循环;
    3. fallthrough:其他语言没有的,贯穿的意思,常用于switch语句中,示例如下:

     

     

    let integerDescribe = 5
    
    var description = "The number (integerDescribe) is"
    
    switch integerDescribe{
    
    case 2,3,5:
    
        description += " a prise number,and also"
    
        fallthrough
    
    default:
    
        description += " an integer.";
    
    }

     

        4.return

    13.函数

    13.1.函数定义

      使用func定义一个函数。调用函数使用它的名字加上小括号中的参数列表。使用->分隔参数的名字和返回值类型。

      函数声明:

    func greet(name:String,day:String) -> String{
    
        return "Hello (name),today is (day)"
    
    }

      函数调用:

    greet("Bob", "Tuesday")

    13.2.无返回值函数

    func sayGoodBye(personName:String){
    
        println("Goodbye,(personName)");
    
    }
    
    sayGoodBye("Tony");

    13.3.多返回值函数

      使用元组类型返回多个值

    func count(string:String) -> (vowels:Int,consonants:Int,others:Int){
    
        var vowel = 0,consonant = 0,other = 0;
    
        for character in string{
    
            switch String(character).lowercaseString{
    
            case "a","e","i","o","u":
    
                ++vowel;
    
            case "b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z":
    
                ++consonant;
    
            default:
    
                ++other;
    
            }
    
        }
    
        return (vowel,consonant,other);
    
    }
    
    let total = count("Some thing is change!");
    
    println("(total.vowels)元音,(total.consonants)辅音")

    13.4.嵌入函数

    func chooseStepFunction(backwards:Bool) -> (Int) -> Int{
    
        func stepForward(input:Int) -> Int{
            return input + 1
        }
    
        func stepBackward(input:Int) -> Int{
            return input - 1
        }
    
        return backwards ? stepBackward : stepForward
    }
    
    var currentValue = -4
    
    // moveNearerToZero是一个函数指针
    let moveNearerToZero = chooseStepFunction(currentValue > 0)
    
    while currentValue != 0{
    
        println("(currentValue)......")
    
        currentValue = moveNearerToZero(currentValue)
    
    }

    14.闭包(Closure)

      语法:

    {(parameters) -> return type in
    
    statements
    
    }

      示例:数组排序

      采用函数实现:

    let names = ["Chris","Alex","Ewa","Barry","Daniella"]
    
    func backwards(s1:String,s2:String) -> Bool{
    
        return s1 > s2
    
    }
    
    // sort排序函数,backwards通过排序规则的函数
    var reversed = sort(names,backwards)
    
    println(reversed)

      采用闭包实现:

    var reversed = sort(names,{(s1:String,s2:String) -> Bool in 
    
    return s1 > s2
    
    })
    
    println(reversed)

    15.类与结构体

      类和结构体有很多共性:

    1. 定义属性存储数据;
    2. 定义方法执行功能处理;
    3. 定义下标,通过下标访问它们的值;
    4. 初始化它们的状态;
    5. 通过扩展(Extension)扩展其功能;
    6. 遵守协议(Protocol),协议提供一种特定的标准功能。

      类比结构体多出的功能:

    1. 能够继承另外一个类;
    2. 能够核对运行期对象的类型;
    3. 析构对象释放资源;
    4. 引用计数允许一个类实例有多个引用。

    15.1.类和结构体的定义

      定义类和结构体:

    class SomeClass{
    
    // class definition goes here
    
    }
    
    struct SomeStructure{
    
    // structure definition goes here
    
    }

      示例:

    struct Resolution{
    
    var width = 0
    
    var height = 0
    
    }
    
    class VideoMode{
    
    var resolution = Resolution()
    
    var interfaced = false
    
    var frameRate = 0.0
    
    var name:String?
    
    }

    15.2.类和结构体的实例化

    struct Resolution{
    
    var width = 0
    
    var height = 0
    
    }
    
    class VideoMode{
    
    var resolution = Resolution()
    
    var interfaced = false
    
    var frameRate = 0.0
    
    var name:String?
    
    }
    
    let someResolution = Resolution()
    
    // let someResolution = Resolution(10,height:20)
    
    let someVideoMode = VideoMode()

    16.属性

    16.1.属性的存储

      属性的主要作用是存储数据,可以分为常量属性和变量属性;

    struct FixedLengthRange{
    
        var firstValue:Int
    
        let length:Int
    
    }
    
    var rangeOfThreeItems = FixedLengthRange(firstValue:0,length:3)
    
    rangeOfThreeItems.firstValue = 6
    // 注意:length是常量属性,值是不可以修改的

    16.2.延时存储属性

      延时存储属性是初始化时候不分配值,直到第一次使用它。属性@lazy声明。

      为什么要用延时存储属性?当一个属性是一个庞大类时,并且这个属性很少用到,那么就可以考虑使用延时存储属性,这样可以避免大量数据加载到内存中。

    class DataImporter{
    
        var fileName = "data.txt"
    
    }
    
    class DataManager{
    
        @lazy var importer = DataImporter()
    
        var data = ""
    
    } 
    
    let manager = DataManager();
    
    manager.data += "Some Data"
    
    manager.data += "Some more data"
    
    println(manager.importer.fileName)

      去掉@lazy关键字在playground里面试试,看看有什么不一样?

    16.3.计算属性

      有的时候一些属性是通过其他的属性计算得出的,通过get和set访问器对其访问。

    // 定义Point
    struct Point{
    
        var x = 0.0,y = 0.0
    
    }
    
    // 定义Size
    struct Size{
    
        var width = 0.0,height = 0.0
    
    }
    
    // 定义Rect
    struct Rect{
    
        var origin = Point()
    
        var size = Size()
    
        var center:Point{
    
        get{
    
            let centerX = origin.x + (size.width / 2)
    
            let centerY = origin.y + (size.height / 2)
    
            return Point(x:centerX,y:centerY)
    
        }
    
        set(newCenter){
    
            origin.x = newCenter.x - (size.width / 2)
    
            origin.y = newCenter.y - (size.height / 2)
    
        }
    
        }
    
    }
    
    var square = Rect(origin:Point(x:0.0,y:0.0),size:Size(10.0,height:20.0))
    
    let initialSquareCenter = square.center
    
    square.center = Point(x:15.0,y:15.0)
    
    println("square origin is now at ((square.origin.x),(square.origin.y))")

    16.4.属性观察者

      为了监听属性的变化,swift通过了属性观察者。

    1. willset观察者是在存储之前调用;
    2. didSet新值存储后调用。
    class StepCounter{
    
        var totalSteps:Int = 0{
    
        willSet(newTotalSteps){
    
            println("About to set totalSteps to (newTotalSteps)")
    
        }
        didSet{
    
            if totalSteps >= oldValue{
    
                println("Added (totalSteps - oldValue) steps")
    
            }
    
        }
    
        }
    
    }
    
    let stepCounter = StepCounter()
    
    stepCounter.totalSteps = 200
    
    stepCounter.totalSteps = 360

    16.5.静态属性

      静态属性在结构体中使用static定义,类中使用class定义。

    struct SomeStructure{
    
        static var storedTypeProperty = "Some Value"
    
    }
    
    class SomeClass{
    
        class var computedTypeProperty:Int{
    
            return 3
    
        }
    
    }

    17.方法

      Swift中的方法是与特定类型(类和结构体)相关的函数

    17.1.方法

    class Counter{
    
        var count = 0
    
        func increment(){
    
            count++
    
        }
    
        func incremmentBy(amount:Int){
    
            count += amount
    
        }
    
        func reset(){
    
            count = 0
    
        }
    
    }
    
    let counter = Counter()
    
    counter.increment()
    
    counter.incremmentBy(5)
    
    counter.reset()

    17.2.使用self

      self代表当前对象。

    struct Point{
    
        var x = 0.0,y = 0.0
    
        func isToTheRightOfX(x:Double) -> Bool{
    
            return self.x > x
    
        }
    
    }
    
    let somePoint = Point(x:4.0,y:5.0)
    
    if somePoint.isToTheRightOfX(1.0){
    
        println("This point is to the right of the line where x == 1.0")
    
    }

    18.下标

    18.1.定义下标

      还记得字典吗?

    var numberOfLegs = ["bird":2,"cat":4,"ant":6]
    
    let birdLeg = numberOfLegs["bird"]

      ["bird"]就是下标

      下标可以在类和结构体中定义

    18.2.只读下标

    struct TimesTable{
    
        let multiplier:Int
    
        subscript(index:Int) -> Int{
    
            return multiplier * index
    
        }
    
    }
    
    let threeTimesTable = TimesTable(multiplier:3)
    
    println("six times three is (threeTimesTable[6])")

    19.继承

      Swift中的类能够继承其他类的属性、方法等。

    19.1.定义基类

    class Vehicle{
    
        var numberOfWheels:Int
    
        var maxPassengers:Int
    
        func description() -> String{
    
            return "(numberOfWheels) wheels;up to (maxPassengers)"
    
        }
    
        init(){
    
            numberOfWheels = 0
    
            maxPassengers = 1
    
        }
    
    }
    
    let someVehicle = Vehicle()

    19.2.定义子类

    class Bicycle:Vehicle{
    
        init() {
    
            super.init()
    
            numberOfWheels = 2
    
        }
    
    }
    
    let bicycle = Bicycle()
    
    println("Bicycle:(bicycle.description())")

    19.3.重写(Overriding)

      子类能够重写父类的方法、属性、下标。

    19.3.1方法重写

    class Vehicle{
    
        var numberOfWheels:Int
    
        var maxPassengers:Int
    
        func description() -> String{
    
            return "(numberOfWheels) wheels;up to (maxPassengers)"
    
        }
    
        init(){
    
            numberOfWheels = 0
    
            maxPassengers = 1
    
        }
    
    }
    
    class Car:Vehicle{
    
        var speed:Double = 0.0
    
        init() {
    
            super.init()
    
            numberOfWheels = 4
    
            maxPassengers = 5
    
        }
    
        override func description() -> String{
    
            return super.description() + ";" + "traveling at (speed)"
    
        }
    
    }
    
    let car = Car()
    
    println("Car:(car.description())")

    19.3.2属性重写

    class Vehicle{
    
        var numberOfWheels:Int
    
        var maxPassengers:Int
    
        func description() -> String{
    
            return "(numberOfWheels) wheels;up to (maxPassengers)"
    
        }
    
        init(){
    
            numberOfWheels = 0
    
            maxPassengers = 1
    
        }
    
    }
    
    class Car:Vehicle{
    
        var speed:Double = 0.0
    
        init() {
    
            super.init()
    
            numberOfWheels = 4
    
            maxPassengers = 5
    
        }
    
        override func description() -> String{
    
            return super.description() + ";" + "traveling at (speed)"
    
        }
    
    }
    
    class SpeedLimitedCar:Car{
    
        override var speed:Double{
    
        get{
    
            return super.speed
    
        }
        set{
    
            super.speed = min(newValue,40.0)
    
        }
    
        }
    
    }
    
    let limitedCar = SpeedLimitedCar()
    
    limitedCar.speed = 60.0
    
    println("SpeedLimitedCar:(limitedCar.description())")

    20.构造器(Initializer)

      为了初始化结构体和类等类型的实例属性。

    20.1.默认构造器

    struct Fahrenheit{
    
        var temperature:Double
    
        init(){
    
            temperature = 32.0
    
        }
    
    }
    
    var f = Fahrenheit()  // 调用默认构造器init(),没有参数和返回值
    
    println("The default temperature is (f.temperature)")

    20.2.自定义构造器

      定义类两个构造器:init(fromFahrenheit:) 和 init(fromKelvin:)

    struct Celsius{
    
        var temperatureInCelsius:Double
    
        init(fromFahrenheit fahrenheit:Double){
    
            temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    
        }
    
        init(fromKelvin kelvin:Double){
    
            temperatureInCelsius = kelvin - 273.15
    
        }
    
    //    init(fahrenheit:Double){
    
    //        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    
    //    }
    
    //    
    
    //    init(kelvin:Double){
    
    //        temperatureInCelsius = kelvin - 273.15
    
    //    }
    
    }
    
    let boilingPointOfWater = Celsius(fromFahrenheit:212.0)
    
    let freezingPointOfWater = Celsius(fromKelvin:273.15)
    
    //let boilingPointOfWater = Celsius(fahrenheit:212.0)
    
    //let freezingPointOfWater = Celsius(kelvin:273.15)

    21.析构器(Deinitializer)

      析构器与构造器相反,在对象释放时候调用。

      使用关键字deinit,语法如下:

    deinit{
    
    }

      实例:

    class Player{
    
        var coinsInPurse:Int
    
        init(coins:Int){
    
            println("call init")
    
            coinsInPurse = coins
    
        }
    
        func winCoins(coins:Int){
    
            coinsInPurse += 10
    
        }
    
        deinit{
    
            coinsInPurse = 0
    
        }
    
    }
    
    var playerOne:Player? = Player(coins:100)
    
    println("PlayerOne has coins (playerOne!.coinsInPurse)")
    
    playerOne = nil;

    22.扩展(Extension)

      在现有类和结构体的基础上,扩展新的功能。

      语法:

    extension SomeType{
    
    }
    
    extension SomeType:SomeProtocol,AnotherProtocol{
    
    }

      OC中的扩展:

    @interface UIImage (UIImageScale)

    22.1.计算属性

    extension Double{
    
        var km:Double{return self * 1000.0}
    
        var m:Double{return self}
    
        var cm:Double{return self / 100.0}
    
        var mm:Double{return self / 1000.0}
    
    }
    
    let oneInch = 25.4.mm
    
    println("OneInch is (oneInch) meters")

    22.2.使用构造器

    struct Size{
    
        var width = 0.0,height = 0.0
    
    }
    
    struct Point{
    
        var x = 0.0,y = 0.0
    
    }
    
    struct Rect{
    
        var origin = Point()
    
        var size = Size()
    
    }
    
    extension Rect{
    
        init(center:Point,size:Size){
    
            let originX = center.x - (size.width / 2)
    
            let originY = center.y - (size.height / 2)
    
            self.init(origin:Point(x:originX,y:originY),size:size)
        }
    }
    
    let centerRect = Rect(center:Point(x:4.0,y:4.0),size:Size(3.0,height:3.0))

    22.3.方法扩展

    extension Int{
    
        func message() -> String{
    
            var message = "";
    
            switch self{
    
            case 0:
    
                message = "成功"
    
            case -1:
    
                message = "用户登录失败"
    
            default:
    
                message = "未知错误"
    
            }
    
            return message;
    
        }
    
    }
    
    3.message();
    
    0.message();
    
    (-1).message();

    23.协议(Protocol)

      协议是为方法、属性等定义一套规范,没有具体的实现。协议能够被类、结构体等具体实现。

    protocol SomeProtocol{
    
    }
    
    struct SomeStructure:SomeProtocol{
    
    }
    
    class SomeClass:SomeProtocol{
    
    }

    23.1.属性

    // 1.set和get访问器
    protocol SomeProtocol{
    
        var mustBeSettable:Int{get set}
    
        var doesNotNeedToBeSettable:Int{get}
    
    }
    
    // 2.静态属性
    protocol AnotherProtocol{
    
        class var someTypeProperty:Int{get set}
    
    }
    
    // 3.只读
    protocol FullyNamed{
    
        var fullName:String{get}
    
    }

      示例:

    protocol FullyNamed{
    
        var fullName:String{get}
    
    }
    
    struct Person : FullyNamed{
    
        var fullName:String
    
    }
    
    let john = Person(fullName:"John Appleseed")
    
    class Starship : FullyNamed{
    
        var prefix:String?
    
        var name:String
    
        init(name:String,prefix:String? = nil){
    
            self.name = name
    
            self.prefix = prefix
    
        }
    
        var fullName:String{
    
        return (prefix ? prefix! + " " : "") + name
    
        }
    
    }
    
    var ncc1701 = Starship(name:"Enterprise",prefix:"USS")
    
    println("(ncc1701.fullName)")

    23.2.方法

    // 1.定义方法
    protocol RandomNumberGenerator{
    
        func random() -> Double
    
    }
    
    
    // 2.定义静态方法
    protocol SomeProtocol{
    
        class func someTypeMethod()
    
    }

      示例:

    class LinearCongruentialGenerator:RandomNumberGenerator{
    
        var lastRandom = 42.0
        let m = 139968.0
        let a = 3877.0
        let c = 29573.0
    
        func random() -> Double{
    
            lastRandom = ((lastRandom * a + c) % m)
    
            return lastRandom / m
    
        }
    
    }
    
    let generator = LinearCongruentialGenerator()
    
    println("Here's a random number:(generator.random())")

    23.3.把协议作为类型使用

    protocol RandomNumberGenerator{
    
        func random() -> Double
    
    }
    
    class LinearCongruentialGenerator:RandomNumberGenerator{
    
        var lastRandom = 42.0
    
        let m = 139968.0
    
        let a = 3877.0
    
        let c = 29573.0
    
        func random() -> Double{
    
            lastRandom = ((lastRandom * a + c) % m)
    
            return lastRandom / m
    
        }
    
    }
    
    class Dice{
    
        let sides:Int
    
        let generator:RandomNumberGenerator
    
        init(sides:Int,generator:RandomNumberGenerator){
    
            self.sides = sides
    
            self.generator = generator
    
        }
    
        func roll() -> Int{
    
            return Int(generator.random() * Double(sides)) + 1
    
        }
    
    }
    
    var d6 = Dice(sides:6,generator:LinearCongruentialGenerator())
    
    for _ in 1...5{
    
        println("Random dice roll is (d6.roll())")
    
    }

    24.Swift的应用

      在这一部分,我实现了一个小Demo:导航栏和Tab栏结合使用。具体代码说明如下:

    24.1.项目结构说明

      主要文件说明:

    1. AppDelegate:系统委托类;
    2. TabBarViewController:Tab栏管理类;
    3. CustomNavigationController:自定义的导航栏类,在这个类里面,做了4英寸屏和3.5英寸屏的处理;
    4. ViewController文件夹:具体的页面控制器;
    5. NSStringExt:对String类型的扩展,主要是IOS7的判断、根据字符串长度返回在控件中显示的高度(常用于UITableViewCell中自适应调整Cell的高度使用);
    6. .......

     24.2.运行效果截图

      iPhone 5S截图:

      iPhone 4S截图:

     24.3.主要代码

      AppDelegate里面:

        func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool
        {
            self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
            
            var tabbarViewCtrl = TabBarViewController(nibName:nil,bundle:nil);
    //        var navigationViewController = UINavigationController(rootViewController:tabbarViewCtrl);
            
            var navigationViewController = CustomNavigationController(rootViewController: tabbarViewCtrl);
            self.window!.rootViewController = navigationViewController;
            
            self.window!.makeKeyAndVisible()
            return true
        }

      TabBarViewController:

        init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
        {
            super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
            
            self.title = "任务";
        }
    
        override func viewDidLoad()
        {
            super.viewDidLoad()
    
            configureTabBar();
        }
    
        override func didReceiveMemoryWarning()
        {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
        
        /*******************************************************************************
        * 方法名称:configureTabBar
        * 功能描述:配置TabBar控件
        * 输入参数:
        * 输出参数:
        ******************************************************************************/
        func configureTabBar()
        {
            self.view.backgroundColor = UIColor.whiteColor();
            self.tabBar.hidden = true;  // 隐藏自带的Tab
            var width = self.view.frame.size.width;
            var height = self.view.frame.size.height;
            
            self.myTabbar = UIView(frame:CGRectMake(0, height - 48 - 64, width, 112));
            let currentVersion = UIDevice.currentDevice().systemVersion;
            
            if (currentVersion.isIos7())
            {
                self.myTabbar!.frame = CGRectMake(0, height - 48, width, 112);
            }
            self.myTabbar!.backgroundColor = UIColor(patternImage:UIImage(named:"tab_bg_ico.png"));
            self.view.addSubview(self.myTabbar);
            self.view.bringSubviewToFront(self.myTabbar);
            
            // 任务
            var btnTask = UIButton.buttonWithType(UIButtonType.Custom) as UIButton;  // 后面必须要加上as UIButton
            btnTask.frame = CGRectMake(0, 0, 80, 48);
            btnTask.tag = 100;
            btnTask.selected = true;
            btnTask.setImage(UIImage(named:"tabtask_sel_ico.png"),forState:UIControlState.Normal);
            btnTask.addTarget(self,action: "tabBarButtonClicked:",forControlEvents:UIControlEvents.TouchUpInside);
            self.myTabbar!.addSubview(btnTask);
            
            // 单据
            var btnBill = UIButton.buttonWithType(UIButtonType.Custom) as UIButton;
            btnBill.frame = CGRectMake(80, 0, 80, 48);
            btnBill.tag = 101;
            btnBill.setImage(UIImage(named:"tabbill_nor_ico.png"),forState:UIControlState.Normal);
            btnBill.addTarget(self,action: "tabBarButtonClicked:",forControlEvents:UIControlEvents.TouchUpInside);
            self.myTabbar!.addSubview(btnBill);
            
            // 查询
            var btnQuery = UIButton.buttonWithType(UIButtonType.Custom) as UIButton;
            btnQuery.frame = CGRectMake(160, 0, 80, 48);
            btnQuery.tag = 102;
            btnQuery.setImage(UIImage(named:"tabquery_nor_ico.png"),forState:UIControlState.Normal);
            btnQuery.addTarget(self,action: "tabBarButtonClicked:",forControlEvents:UIControlEvents.TouchUpInside);
            self.myTabbar!.addSubview(btnQuery);
            
            // 设置
            var btnSetting = UIButton.buttonWithType(UIButtonType.Custom) as UIButton;
            btnSetting.frame = CGRectMake(240, 0, 80, 48);
            btnSetting.tag = 103;
            btnSetting.setImage(UIImage(named:"tabset_nor_ico.png"),forState:UIControlState.Normal);
            btnSetting.addTarget(self,action:"tabBarButtonClicked:",forControlEvents:UIControlEvents.TouchUpInside);
            self.myTabbar!.addSubview(btnSetting);
            
            var taskViewCtrl = MyTaskViewController(nibName:"MyTaskViewController",bundle:nil);
            var billViewCtrl = MyBillViewController();
            var queryViewCtrl = QueryViewController(nibName:"QueryViewController",bundle:nil);
            var settingViewCtrl = SettingViewController(nibName:"SettingViewController",bundle:nil);
            
            self.viewControllers = [taskViewCtrl,billViewCtrl,queryViewCtrl,settingViewCtrl];
        }
        
        /*******************************************************************************
        * 方法名称:configureTabBar
        * 功能描述:配置TabBar控件
        * 输入参数:
            sender:事件源
        * 输出参数:
        ******************************************************************************/
        func tabBarButtonClicked(sender:UIButton)
        {
            var index       = sender.tag;
            var btnTask     = self.view.viewWithTag(100) as UIButton
            var btnBill     = self.view.viewWithTag(101) as UIButton
            var btnQuery    = self.view.viewWithTag(102) as UIButton
            var btnSetting  = self.view.viewWithTag(103) as UIButton
            
            switch index{
                case 100:  // 任务
                    self.title = "任务";
                    btnTask.selected    = true;
                    btnBill.selected    = false;
                    btnQuery.selected   = false;
                    btnSetting.selected = false;
                    btnTask.setImage(UIImage(named:"tabtask_sel_ico.png"),forState:UIControlState.Normal);
                    btnBill.setImage(UIImage(named:"tabbill_nor_ico.png"),forState:UIControlState.Normal);
                    btnQuery.setImage(UIImage(named:"tabquery_nor_ico.png"),forState:UIControlState.Normal);
                    btnSetting.setImage(UIImage(named:"tabset_nor_ico.png"),forState:UIControlState.Normal);
                case 101:  // 单据
                    self.title = "单据";
                    btnTask.selected    = false;
                    btnBill.selected    = true;
                    btnQuery.selected   = false;
                    btnSetting.selected = false;
                    btnTask.setImage(UIImage(named:"tabtask_nor_ico.png"),forState:UIControlState.Normal);
                    btnBill.setImage(UIImage(named:"tabbill_sel_ico.png"),forState:UIControlState.Normal);
                    btnQuery.setImage(UIImage(named:"tabquery_nor_ico.png"),forState:UIControlState.Normal);
                    btnSetting.setImage(UIImage(named:"tabset_nor_ico.png"),forState:UIControlState.Normal);
                case 102:  // 查询
                    self.title = "查询";
                    btnTask.selected    = false;
                    btnBill.selected    = false;
                    btnQuery.selected   = true;
                    btnSetting.selected = false;
                    btnTask.setImage(UIImage(named:"tabtask_nor_ico.png"),forState:UIControlState.Normal);
                    btnBill.setImage(UIImage(named:"tabbill_nor_ico.png"),forState:UIControlState.Normal);
                    btnQuery.setImage(UIImage(named:"tabquery_sel_ico.png"),forState:UIControlState.Normal);
                    btnSetting.setImage(UIImage(named:"tabset_nor_ico.png"),forState:UIControlState.Normal);
                case 103:  // 设置
                    self.title = "设置";
                    btnTask.selected    = false;
                    btnBill.selected    = false;
                    btnQuery.selected   = false;
                    btnSetting.selected = true;
                    btnTask.setImage(UIImage(named:"tabtask_nor_ico.png"),forState:UIControlState.Normal);
                    btnBill.setImage(UIImage(named:"tabbill_nor_ico.png"),forState:UIControlState.Normal);
                    btnQuery.setImage(UIImage(named:"tabquery_nor_ico.png"),forState:UIControlState.Normal);
                    btnSetting.setImage(UIImage(named:"tabset_sel_ico.png"),forState:UIControlState.Normal);
                default:
                    println("No Selected Items");
            }
            
            self.selectedIndex = index - 100;
        }

      CustomNavigationController:

    class CustomNavigationController: UINavigationController
    {
        init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
        {
            super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
            // Custom initialization
        }
        
        init(rootViewController: UIViewController!)
        {
            return super.init(rootViewController: rootViewController);
        }
    
        override func viewDidLoad()
        {
            super.viewDidLoad()
            
            let currentVersion = UIDevice.currentDevice().systemVersion;
    
            if (currentVersion.isIos7())
            {
                self.navigationBar.setBackgroundImage(UIImage(named:"navbg_ico.png").stretchableImageWithLeftCapWidth(20,topCapHeight: 30),forBarMetrics:UIBarMetrics.Default);
            }
            else
            {
                self.navigationBar.setBackgroundImage(UIImage(named:"navbg_ico.png"),forBarMetrics:UIBarMetrics.DefaultPrompt);
            }
        }
    
        override func didReceiveMemoryWarning()
        {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
        
        override func pushViewController(viewController: UIViewController!, animated: Bool)
        {
            super.pushViewController(viewController,animated:animated);
        }
        
        override func popViewControllerAnimated(animated: Bool) -> UIViewController!
        {
            return super.popViewControllerAnimated(animated);
        }
    }

      MyTaskViewController

        override func viewDidLoad()
        {
            super.viewDidLoad()
    
            self.tableView.registerClass(UITableViewCell.self,forCellReuseIdentifier: "Cell");
        }
        
        override func viewWillAppear(animated: Bool)
        {
            var width = self.view.frame.size.width
            var height = self.view.frame.size.height
            
            self.tableView.frame = CGRectMake(0, 0, width, height - 48);
        }
    
        override func didReceiveMemoryWarning()
        {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
        
        // =========================================================================
        // Table view data source
        
        func numberOfSectionsInTableView(tableView: UITableView!) -> Int
        {
            return 1;
        }
        
        func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int
        {
            return 50;
        }
        
        func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat
        {
            return 56;
        }
        
        func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
        {
            let cell = tableView .dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell;
            var lblBillCode = UILabel(frame:CGRectMake(10,4,140,22));
            lblBillCode.text = "JTBX1404020601";
            lblBillCode.font = UIFont(name: "Arial",size: 16);
            
            cell.addSubview(lblBillCode);
            var lblContent = UILabel(frame:CGRectMake(160,4,150,22));
            lblContent.text = "市内交通费用报销单";
            lblContent.textAlignment = NSTextAlignment.Right;
            lblContent.font = UIFont(name: "Arial",size: 16);
            cell.addSubview(lblContent);
            
            var lblTime = UILabel(frame:CGRectMake(160,30,150,22));
            lblTime.text = "2014-05-23 22:10:10";
            lblTime.font = UIFont(name: "Arial",size: 14);
            lblTime.textColor = UIColor.grayColor();
            lblTime.textAlignment = NSTextAlignment.Right;
            cell.addSubview(lblTime);
            return cell;
        }
        
        // =========================================================================
        // Table view data delegate
        
        func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!){
            println("row = %d",indexPath.row)
        }

      NSStringExt:

    extension String {
        
        /*******************************************************************************
        * 方法名称:isIos7
        * 功能描述:配置TabBar控件
        * 输入参数:
        * 输出参数:true:IOS7及以上系统;false:IOS7以下系统。
        ******************************************************************************/
        func isIos7() -> Bool?
        {
            return self >= "7.0"
        }
        
        func stringHeightWith(fontSize:CGFloat,CGFloat)->CGFloat
        {
            var font = UIFont.systemFontOfSize(fontSize)
            var size = CGSizeMake(width,CGFLOAT_MAX)
            var paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineBreakMode = .ByWordWrapping;
            var  attributes = [NSFontAttributeName:font,
                NSParagraphStyleAttributeName:paragraphStyle.copy()]
            
            var text = self as NSString
            var rect = text.boundingRectWithSize(size, options:.UsesLineFragmentOrigin, attributes: attributes, context:nil)
            return rect.size.height
        }
    } 

      源码下载

  • 相关阅读:
    "分段器"组件:<segment> —— 快应用组件库H-UI
    "页内标签"组件:<tab> —— 快应用组件库H-UI
    "标签栏"组件:<main-tab> —— 快应用组件库H-UI
    "导航栏"组件:<nav-bar> —— 快应用组件库H-UI
    如何配置pch文件
    如何清除Xcode8打印的系统日志
    iOS打包ipa给客户测试流程
    如何安装ipa文件
    如何获取苹果手机的UDID
    iOS键盘输入屏幕上移
  • 原文地址:https://www.cnblogs.com/eagle927183/p/3842476.html
Copyright © 2011-2022 走看看