swift_swiftyjson - CSDN
swift 订阅
Swift,苹果于2014年WWDC苹果开发者大会发布的新开发语言,可与Objective-C共同运行于macOS和iOS平台,用于搭建基于苹果平台的应用程序。Swift是一款易学易用的编程语言,而且它还是第一套具有与脚本语言同样的表现力和趣味性的系统编程语言。Swift的设计以安全为出发点,以避免各种常见的编程错误类别。 [1]  2015年12月4日,苹果公司宣布其Swift编程语言开放源代码。长600多页的The Swift Programming Language [2]  可以在线免费下载。 展开全文
Swift,苹果于2014年WWDC苹果开发者大会发布的新开发语言,可与Objective-C共同运行于macOS和iOS平台,用于搭建基于苹果平台的应用程序。Swift是一款易学易用的编程语言,而且它还是第一套具有与脚本语言同样的表现力和趣味性的系统编程语言。Swift的设计以安全为出发点,以避免各种常见的编程错误类别。 [1]  2015年12月4日,苹果公司宣布其Swift编程语言开放源代码。长600多页的The Swift Programming Language [2]  可以在线免费下载。
信息
源    于
Objective-C
外文名
Swift
发布时间
2014年6月2日
发行组织
Apple
中文名
雨燕
参考语言
C,JavaScript,Python,Java
系    统
macOS,iOS,linux
SWIFT发展历史
2014-6-3 Swift于WWDC苹果开发者大会发布。 发布(6张) 2014-6-4 《Swift中文版》翻译组在github上进行协同翻译 [3]  。此项目开始不到一周就获得了1067个star。该项目的发起人是北航的大三学生 [4]  。2014-6-12《Swift中文版》第一版发布 [5]  。2015年12月4日,苹果公司宣布其Swift编程语言开放源代码 [3]  。长600多页的The Swift Programming Language [2]  可以在线免费下载。同时可以在苹果官方Github下载 [3]  。2020年最新一期的编程语言排行榜显示,Swift从第15名上升至第9名。 [6] 
收起全文
  • 从零开始学Swift——语法篇 第一季

    万人学习 2018-10-22 21:38:04
    本视频主要介绍Swift程序开发环境、Swift 语法基础、运算符、Swift原生数据类型、Swift原生字符串、控制语句。本视频是基 于Swift2.x版本录制,与图书《从零开始学Swift》语法篇同步讲解。是学习Swift视频,进行iOS...
  • Swift5语言入门实例教程

    千人学习 2019-12-05 11:06:29
    包含常量与变量、基本数据类型,以及Swift语言中的新数据类型—元组型和可选型的内容。同时还讲解了运算符和表达式、流程控制语句、字符和字符串、集合类型、函数和闭包。此外,Swift面向对象的枚举、结构体、类,...
  • Swift编程语言(Swift 5)

    2020-07-29 14:19:59
    介绍: 《Swift 编程语言》是苹果官方对 Swift 语言做的权威指南,很遗憾苹果公司并没有进行多语言支持。所以我独立发起了这个手册的翻译工作——与其他现存翻译不同的是:它同步更新苹果官方的 Swift 开发者预览版 ...
  • Swift 5 基础语法篇

    千次阅读 2019-09-02 16:16:43
    常量 只赋值一次,它的值不要求在编译时期确定值,但在使用之前赋值一次 let a = 10 let b: Int = 20 let c: Int c = a + b 标识符 标识符(常量变量函数名)不能用数字开头,不能包含空白字符、制表符、箭头等特殊...

    常量

    只赋值一次,它的值不要求在编译时期确定值,但在使用之前赋值一次

    let a = 10 
    let b: Int = 20
    let c: Int
    c = a + b
    

    标识符

    标识符(常量变量函数名)不能用数字开头,不能包含空白字符、制表符、箭头等特殊字符。??是可以的


    数据类型

    值类型: 枚举: Optional
    结构体: Bool,Int,Float,Double,Character,String,Array,Dictionary,Set

    引用类型: 类


    字面量

    Bool、String、Character、整数、浮点数、数组、字典等的值
    数字字数多可以添加"_" 分割位数


    类型转换

    不同类型的常量变量不能相互进行运算


    元组

    let error = (404, "Not Found")
    error.0
    error.1
    
    let (statusCode, statusMessage) = error
    
    let (statusCode, _) = error
    
    let httpError = (statusCode: 200, description: "OK")
    httpError. statusCode
    

    展开全文
  • SwiftUI入门到实战课程

    千人学习 2020-01-31 12:27:32
    SwiftUI是一种创新、简单的iOS开发中的界面布局方案,可以通过Swift语言的强大功能,在所有的Apple平台上快速构建用户界面。 仅使用一组工具和API为任何Apple设备构建用户界面。 SwiftUI具有易于阅读和自然编写的...
  • Swift快速入门

    2020-09-08 06:36:46
    Swift中规定:在定义一个标识符时必须明确说明该标识符是一个常量还是变量 1、使用 let 定义常量,定义之后不可以修改 let number = 10 // 常量不可以修改 number = 20 ❌ 2、使用 var 定义变量,定义之后可以...

    一、常量&变量

    在Swift中规定:在定义一个标识符时必须明确说明该标识符是一个常量还是变量

    1、使用 let 定义常量,定义之后不可以修改

    let number = 10
    // 常量不可以修改
    number = 20 ❌

    2、使用 var 定义变量,定义之后可以修改

    var number = 10
    
    number = 20 

    ⚠️编译器会根据给变量或常量所赋的值,推断它的数据类型。所以这里系统会认为number是Int类型的

    ⚠️ swift中输出语句:print函数

    print("Hello Swift")

    二、数据类型

    Swift中的数据类型也有:整型/浮点型/字符串/对象类型/结构体类型等等

    ⚠️ Swift是强类型语言

    // 定义变量时没有指定明确的类型,但是因为赋值给i一个20.20为整型.因此i为整型
    var i = 20
    // 如果之后赋值给i一个浮点型数值,则会报错
    // i = 30.5 ❌

    如果定义一个标识符时有直接进行赋值,那么标识符后面的类型可以省略

    如果想要指定常量或变量的数据类型

    var number:Float = 10
    var name:String = "花花"

    Swift中的基本运算

    ⚠️ Swift中在进行基本运算时必须保证类型一致,否则会出错

    ⚠️ 值不会隐式转换,需要显示转换成其他数据类型

    let a = 10
    let b = 3.14
    
    // 错误写法
    // let c = a + b ❌
    // let c = a * b ❌
    
    // 正确写法
    let c = Double(a) + b
    let d = a + Int(b)

    三、字符串

    字符串的使用

    1、遍历字符串

    // 字符串遍历
    var str = "Hello, Swift"
    for c in str {
        print(c)
    }

    2、字符串拼接

    let str1 = "Hello"
    let str2 = "Swift"
    let str3 = str1 + str2

    3、字符串插值

    let age = 18
    let result = "My name is Huahua, age is \(age)"

    4、字符串的格式化

    let str = String(format: "%@=%@", key, value)

    5、使用2对3引号可以表示多行字符串

    let string = """
    Hello Swift!
    Hello Swift!
    Hello Swift!
    """

    ⚠️引号所在行,引号后不能有其他元素

    四、数组

    数组是一串有序的由相同类型元素构成的集合,数组中的集合元素是有序的,可以重复出现

    ⚠️ 声明数组

    // let代表不可变数组
    let array:Array<String>
    
    // var代表可变数组
    var array: [String]

    ⚠️ 初始化数组

    // 定义一个可变数组,必须初始化才能使用
    var array1 : [String] = [String]()
    
    // 定义一个不可变数组
    let array2 : [Any] = ["花花", 18]
    
    // 定义时直接初始化
    var array = ["a", "b", "c"]
    
    // 先定义,后初始化
    var array : Array<String>
    array = ["a", "b", "c"]

    2、对数组的基本操作

    // 添加数据
    array.append("abc")
    
    // 删除元素
    array.removeFirst()
    
    // 修改元素
    array[0] = "asd"
    
    // 取值
    array[1]
    
    // 数组合并
    // 注意:只有相同类型的数组才能合并
    var array1 = ["a", "b","c"]
    var array2 = ["d", "e"]
    var array3 = array1 + array2

    3、数组的遍历

    // 遍历数组
    for i in 0..<array.count {
        print(array[i])
    }
    
    // forin方式
    for item in array {
        print(item)
    }
    
    // 设置遍历的区间
    for item in array[0..<2] {
        print(item)
    }

    五、字典

    字典是由两部分集合构成的,一个是键(key)集合,一个是值(value)集合。键集合是不能有重复元素的,值集合可以重复,键和值是成对出现的。

    1、字典的初始化

    // 定义一个可变字典
    var dict1 : [String : Any] = [String : Any]()
    
    // 定义一个不可变字典
    let dict2 = ["name" : "花花", "age" : 18]

    ⚠️ 声明字典

    var dict1: Dictionary<Int, String>
    var dict2: [Int: String]

    2、字典的基本操作

    // 添加数据
    dict["height"] = 1.88
    
    // 删除字段
    dict.removeValueForKey("height")
    
    // 修改字典
    dict["name"] = "花花"
    
    // 查询字典
    dict["name"]
    
    // 字典的合并
    var dict1 = ["name" : "花花", "age" : 18]
    var dict2 = ["height" : 1.8]
    
    // 字典不可以直接相加合并
    for (key, value) in dict2 {
        dict1[key] = value
    }

    3、字典的遍历

    // 遍历字典中所有的值
    for value in dict.values {
        print(value)
    }
    
    // 遍历字典中所有的键
    for key in dict.keys {
        print(key)
    }
    
    // 遍历所有的键值对
    for (key, value) in dict {
        print(key)
        print(value)
    }

    六、元祖

    元祖是一种数据结构,类似于数组或字典,用于定义一组数据

    1、定义元祖

    ("1001", "花花", 18, 90)
    (id:"1001", name:"张三", age:18, score:90)

    2、元祖的简单使用

    // 元祖:HTTP错误
    // 写法一:
    let error = (404, "Not Found")
    print(error.0)
    print(error.1)
    
    // 写法二:
    let error = (errorCode : 404, errorInfo : "Not Found")
    print(error.errorCode)
    print(error.errorInfo)
    
    // 写法三:
    let (errorCode, errorIno) = (404, "Not Found")
    print(errorCode)
    print(errorIno)

    七、可选类型(Optional)

    在swift开发中,nil也是一个特殊的类型。

    1、可选类型的定义

    // 写法一:定义可选类型
    let string : Optional<String> = nil
    
    // 写法二:定义可选类型,语法糖(常用)
    let string : String? = nil
    
    // 错误写法
    // let string : String = nil ❌

    2、可选类型的使用

    // 定义可选类型
    var string : String? = nil
    
    // 给可选类型赋值
    string = "Hello world"
    
    // 打印结果
    print(string)
    
    // 结果:Optional("Hello world")
    // 因为打印出来的是可选类型,所有会带Optional

    3、解包

    解包就是取出可选类型的真实值

    print(string!) // 结果:Hello world
    
    ⚠️注意:如果可选类型为nil,强制取出其中的值(解包),程序会崩溃
    
    string = nil
    print(string!) // 报错 
    
    // 正确写法:
    if string != nil {
        print(string!)
    }
    
    // 简单写法:为了让在if语句中可以方便使用string
    if var str = string {
        print(str)
    }

    4、可选类型使用实例

    // 通过该方法创建的URL,可能有值,也可能没有值
    
    // 正确写法:使用可选类型来接收
    let url : URL? = URL(string: "http://www.baidu.com")
    
    // 错误写法:如果返回值是nil时,就不能接收了
    let url : URL = URL(string: "http://www.baidu.com")
    
    // 通过url来创建request对象
    if let tempUrl = url {
        let request = NSURLRequest(URL: tempUrl)
    }

    八、函数

    函数格式:

    func 函数名(参数列表) -> 返回值类型 {
        代码块
        return 返回值
    }
    • func是关键字,多个参数列表之间可以用逗号(,)分隔,也可以没有参数
    • 使用箭头“->”指向返回值类型
    • 如果函数没有返回值,返回值为Void.“-> 返回值类型”部分可以省略

    1、常见函数类型

    <1 没有参数,没有返回值

    func test() -> Void {
        print("Hello Swift")
    }
    
    // 调用函数
    test()
    
    // 简单写法
    // 如果没有返回值,后面的内容可以都不写
    func test2() {
       print("Hello Swift")
    }

    <2 有参数,没返回值

    func test(name : String) {
        print("Hello\(name)")
    }
    test(name: "Swift")

    <3 没参数,有返回值

    func getSth() -> String {
        return "花花"
    }
    var str = getSth()
    print(str)

    <4 有参数,有返回值

    func sum(num1 : Int, num2 : Int) -> Int {
        return num1 + num2
    }
    var result = sum(num1: 20, num2: 30)
    print(result)

    2、外部参数&内部参数

    在函数外面可以看到的参数,就是外部参数。在函数内部可以看到的参数,就是内部参数。

    ⚠️ 如果不想要外部参数,可以在参数名称前加_

    // number1、number2和number3是外部参数的名称
    
    func mutiple(number1 num1 : Int, number2 num2 : Int, number3 num3 : Int) -> Int {
        return num1 * num2 * num3
    }
    var result1 = mutiple(number1: 20, number2: 4, number3: 5)

    3、默认参数

    某些情况,如果没有传入具体的参数,可以使用默认参数

    func makecoffee(type :String = "卡布奇诺") -> String {
        return "制作一杯\(type)咖啡。"
    }
    
    let coffee1 = makecoffee("拿铁")
    let coffee2 = makecoffee()

    4、可变参数

    swift中函数的参数个数可以变化,它可以接受不确定数量的输入类型参数(必须具有相同的类型),我们可以通过在参数类型名后面加入(...)的方式来指示这是可变参数

    func sum(numbers:Double...) -> Double {
        var total: Double = 0
        for number in numbers {
            total += number
        }
        return total
    }
    
    sum(100.0, 20, 50)

    5、引用类型

    默认情况下,函数的参数是值传递.如果想改变外面的变量,则需要传递变量的地址

    inout关键字

    func swap(a : inout Int, b : inout Int) {
       let temp = a
       a = b
       b = temp
    }
    
    var a = 10
    var b = 20
    swap(a: &a, b: &b)
    print("a:\(a), b:\(b)")

    6、方法重载

    方法重载:方法名称相同,但是参数不同

    func mutiple(_ num1: Int, _ num2 :Int) -> Int {
        return num1 * num2
    }
    
    var result2 = mutiple(20, 20)

    九、 闭包

    闭包是一个特殊函数

    1、定义闭包

    类型:(形参列表)->(返回值)

    技巧:定义闭包类型时,直接写()->().再填充参数和返回值

    {
        (形参) -> 返回值类型 in
        // 执行代码
    }

    2、闭包的使用

    // 定义网络请求类
    class HttpTool: NSObject {
        func loadRequest(callBack: ()->()){
            print("加载数据..")
            callBack()
        }
    }
    
    // 网络请求
    let httpTool = HttpTool()
    httpTool.loadRequest ({ () -> () in
        print("加载完成")
    })   

    3、闭包的简写

    • 如果闭包没有参数,没有返回值.in和in之前的内容可以省略
    httpTool.loadRequest({
        print("加载完成")
    })

    ⚠️ 尾随闭包

    • 尾随闭包写法
      • 如果闭包是函数的最后一个参数,则可以将闭包写在()后面
      • 如果函数只有一个参数,并且这个参数是闭包,那么()可以不写
    httpTool.loadRequest() {
        print("加载完成")
    }
    // 开发中建议该写法
    httpTool.loadRequest {
        print("加载完成")
    }

    4、闭包的循环使用

    • 如果在HttpTool中有对闭包进行强引用,则会形成循环引用
    class HttpTool: NSObject {
        // 定义属性,强引用传入的闭包
        var callBack : (()->())?
    
        func loadRequest(callBack : ()->()){
            callBack()
            self.callBack = callBack
        }
    }
    • swift中解决循环引用的方式
    // [weak self] () -> () in
    httpTool.loadRequest { [weak self] in
        self.view.backgroundColor = UIColor.redColor()
    }

    十、 懒加载

    定义:用到时候才加载

    懒加载的本质是,在第一次使用的时候执行闭包,将闭包的返回值赋值给属性

    • lazy的作用是只会赋值一次
    lazy var array : [String] = {
        () -> [String] in
        return ["a", "b", "c"]
    }()

    十一、类

    Swift是一门面向对象开发的语言,面向对象的基础是类

    1、类的定义

    class 类名 : SuperClass {
        // 定义属性和方法
    }

    ⚠️ 定义的类,可以没有父类.那么该类是 rootClass

    2、类的属性

    • Swift中类的属性有多种
      • 存储属性:存储实例的常量和变量
      • 计算属性:通过某种方式计算出来的属性
      • 类属性:与整个类自身相关的属性

    存储属性

    • 存储属性是最简单的属性,它作为类实例的一部分,用于存储常量和变量
    • 可以给存储属性提供一个默认值,也可以在初始化方法中对其进行初始化
    class Student : NSObject {
        // 存储属性
        var age : Int = 0
        var name : String?
        var englishScore : Double = 0.0
        var mathScore : Double = 0.0
    }
    
    // 创建学生对象
    let stu = Student()
    // 给存储属性赋值
    stu.age = 10
    stu.name = "花花"
    stu.englishScore = 80.0
    stu.mathScore = 90.0

    计算属性

    • 计算属性并不存储实际的值,而是提供一个getter和一个可选的setter来间接获取和设置其它属性
    • 存储属性一般只提供getter方法
    • 如果只提供getter,而不提供setter,则该计算属性为只读属性,并且可以省略get{}
    class Student : NSObject {
        // 存储属性
        var age : Int = 0
        var name : String?
        var englishScore : Double = 0.0
        var mathScore : Double = 0.0
        
        // 计算属性
        var averageScore : Double {
            get {
                return (englishScore + mathScore) / 2
            }
            // newValue是系统分配的变量名,内部存储着新值
            set {
                self.averageScore = newValue
            }
        }
    }

    类属性

    • 类属性是与类相关联的,而不是与类的实例相关联
    • 类属性使用static来修饰
    class Student : NSObject {
        // 存储属性
        var age : Int = 0
        var name : String?
    
        var englishScore : Double = 0.0
        var mathScore : Double = 0.0
    
        // 计算属性
        var averageScore : Double {
            get {
                return (englishScore + mathScore) / 2
            }
    
            // 没有意义.newValue是系统分配的变量名,内部存储着新值
            set {
                self.averageScore = newValue
            }
        }
    
        // 类属性
        static var corseCount : Int = 0
    }
    
    // 设置类属性的值
    Student.corseCount = 3

    3、监听属性的改变

    Swift中可以通过属性观察者来监听和响应属性值的变化

    • 通常是监听存储属性和类属性的改变.(对于计算属性,我们不需要定义属性观察者,因为我们可以在计算属性的setter中直接观察并响应这种值的变化)

    • 我们通过设置以下观察方法来定义观察者

      • willSet:在属性值被存储之前设置。此时新属性值作为一个常量参数被传入。该参数名默认为newValue,我们可以自己定义该参数名
      • didSet:在新属性值被存储后立即调用。与willSet相同,此时传入的是属性的旧值,默认参数名为oldValue
    class Person : NSObject {
        var name : String? {
            // 可以给newValue自定义名称
            willSet (){ 
                // 属性即将改变,还未改变时会调用的方法
                // 在该方法中有一个默认的系统属性newValue,用于存储新值
                print(newValue)
            }
            didSet (oldValue) {
                // 属性值已经改变了,会调用的方法
                // 在该方法中有一个默认的系统属性oldValue,用于存储旧值
                print(oldValue)
            }
        }
        var age : Int = 0
        var height : Double = 0.0
    }
    
    let p : Person = Person()
    
    // 在赋值时,监听该属性的改变
    // 在OC中是通过重写set方法
    // 在swift中,可以给属性添加监听器
    p.name = "花花"

    十二、类的构造函数

    • 创建一个类时,必然会调用一个构造函数
    • 即便是没有编写任何构造函数,编译器也会提供一个默认的构造函数。
    • 如果是继承自NSObject,可以对父类的构造函数进行重写

    1、构造函数的基本使用

    class Person: NSObject {
        var name : String = ""
        var age : Int = 0
    
        // 重写了NSObject(父类)的构造方法
        override init() {
            name = ""
            age = 0
        }
    }
    
    // 创建一个Person对象
    let p = Person()

    2、初始化时给属性赋值

    很多时候,我们在创建一个对象时就会给属性赋值,可以自定义构造函数 ⚠️ 如果自定义了构造函数,会覆盖init()方法.即不在有默认的构造函数

    class Person: NSObject {
        var name : String?
        var age : Int = 0
    
        // 自定义构造函数,会覆盖init()函数
        init(name : String, age : Int) {
            self.name = name
            self.age = age
        }
    }
    
    // 创建一个Person对象
    let p = Person(name: "花花", age: 18)

    十三、Swift逻辑分支

    通过分支语句可以控制程序的执行流程

    • 在Swift的判断句中必须有明确的真假 false/true

    1、if语句

    let a = 10
    
    // 错误写法:❌
    //if a {
    //    print("a")
    //}
    
    // 正确写法
    if a > 9 {
        print(a)
    }

    这个是可选类型,因为只有声明成可选类型后,才可以判断是否为空

    let view : UIView? = UIView()
    
    // 判断如果view有值,则设置背景颜色
    // 错误写法 ❌
    //if view {
    //    view.backgroundColor = UIColor.redColor()
    //}
    
    if view != nil {
        view!.backgroundColor = UIColor.redColor()
    }

    2、if/else if/else 语句

    let score = 87
    
    if score < 60 {
        print("不及格")
    } else if score <= 70 {
        print("及格")
    } else if score <= 80 {
        print("良好")
    } else if score <= 90 {
        print("优秀")
    } else {
        print("完美")
    }

    3、三目运算符

    var a = 10
    var b = 50
    
    var result = a > b ? a : b
    print(result)

    4、guard语句

    guard是Swift2.0新增的语法,它设计的目的是提高程序的可读性

    • guard语法:
      • 当条件表达式为true时候跳过else语句中的内容,执行后面的代码
      • 条件表达式为false时候执行else语句中的内容,跳转语句一般是return、break、continue和throw
    guard 条件表达式 else {
        // do sth..
        return
    }
    do sth...

    使用实例:

    var age = 18
    
    func online(age : Int) -> Void {
        guard age >= 18 else {
            print("回家去")
            return
        }
    
        print("可以上网")
    }
    
    online(age)

    5、switch分支

    switch后可以不跟(),case后可以不跟break(默认会有break)

    let sex = 0
    
    switch sex {
    case 0 :
        print("男")
    case 1 :
        print("女")
    default :
        print("其他")
    }

    如果希望出现之前的case穿透,则可以使用关键字fallthrough

    let sex = 0
    
    switch sex {
    case 0:
        fallthrough
    case 1:
        print("正常人")
    default:
        print("其他")
    }

    swift支持多种数据类型

    • 浮点型的switch判断
    let f = 3.14
    switch f {
    case 3.14:
        print("π")
    default:
        print("not π")
    }
    • 字符串类型
    let opration = "+"
    
    switch opration {
        case "+":
            print("+")
        case "-":
            print("-")
        case "*":
            print("*")
        case "/":
            print("/")
    default:
        break
    }
    • switch支持区间判断
    let score = 88
    
    switch score {
    case 0..<60:
        print("不及格")
    case 60..<80:
        print("及格")
    case 80..<90:
        print("良好")
    case 90..<100:
        print("优秀")
    default:
        print("满分")
    }

    十四、循环

    1、for循环

    for i in 0..<10 {
        print(i)
    }
    
    for i in 0...10 {
        print(i)
    }

    2、while循环

    var a = 0
    while a < 10 {
        a++
    }

    3、repeat while 循环

    let b = 0
    repeat {
        print(b)
        b++
    } while b < 20

     

     

    展开全文
  • swift 列表

    2020-09-15 17:40:59
    // Product.swift // geekTime // // Created by liuan on 2020/9/14. // Copyright © 2020 liuan. All rights reserved. // import Foundation struct Product { var name:String var price: Int var ...

    效果

    构造

    //
    //  Product.swift
    //  geekTime
    //
    //  Created by liuan on 2020/9/14.
    //  Copyright © 2020 liuan. All rights reserved.
    //
    
    import Foundation
    
    struct Product {
        var name:String
        var price: Int
        var imageUrl:String
        var desc:String
        var teacher:String
        var total:Int
        var update:Int
        var detail:String
        var curseList:String
        var studentCount:Int
    }
    

    假数据

    //
    //  FakeData.swift
    //  geekTime
    //
    //  Created by liuan on 2020/9/14.
    //  Copyright © 2020 liuan. All rights reserved.
    //
    
    import Foundation
    class FakeData {
        private static  var bannerList = [String]()
        private static var products = [Product]()
        private static var deals=[Deal]()
        
        static func createBanners()->[String]{
            if bannerList.count == 0 {
                bannerList = [
                    "https://via.placeholder.com/450x150",
                    "https://via.placeholder.com/450x151",
                    "https://via.placeholder.com/450x152"
                ]
            }
            return bannerList
        }
        
        static func createProducts()->[Product]{
            if products.count == 0 {
                products = [
                    Product(name: "项目实战20讲", price: 1, imageUrl: "https://via.placeholder.com/254x336", desc: "当下,项目杀手狂妃卡欢乐颂发货啦好看货收到了粉红色的两幅画打发链接", teacher: "刘安", total: 20, update: 9, detail: "dasdjaskldjasldjasldsadlk", curseList: "开篇词(1)", studentCount: 234234),
                    Product(name: "项目实战18讲", price: 2, imageUrl: "https://via.placeholder.com/254x336", desc: "当下,项目杀手狂妃卡欢乐颂发货啦好看货收到了粉红色的两幅画打发链接", teacher: "刘安", total: 20, update: 9, detail: "dasdjaskldjasldjasldsadlk", curseList: "开篇词(1)", studentCount: 234234),
                    Product(name: "项目实战19讲", price: 3, imageUrl: "https://via.placeholder.com/254x336", desc: "当下,项目杀手狂妃卡欢乐颂发货啦好看货收到了粉红色的两幅画打发链接", teacher: "刘安", total: 20, update: 9, detail: "dasdjaskldjasldjasldsadlk", curseList: "开篇词(1)", studentCount: 234234),
                    Product(name: "项目实战21讲", price: 4, imageUrl: "https://via.placeholder.com/254x336", desc: "当下,项目杀手狂妃卡欢乐颂发货啦好看货收到了粉红色的两幅画打发链接", teacher: "刘安", total: 20, update: 9, detail: "dasdjaskldjasldjasldsadlk", curseList: "开篇词(1)", studentCount: 234234)
                ]
            }
            return products
        }
        
        
        static func createsDeals() -> [Deal]{
            if deals.count == 0 {
                deals = FakeData.createProducts().map {
                    Deal(product: $0, process: 1)
                }
                
            }
            return deals
            
            
        }}
    

    单独把列表拎出来

    //
    //  ProductList.swift
    //  geekTime
    //
    //  Created by liuan on 2020/9/15.
    //  Copyright © 2020 liuan. All rights reserved.
    //
    
    import Foundation
    import UIKit
    import Kingfisher
    class ProductCell: UITableViewCell {
        let priceLabel:UILabel
        let productImageView: UIImageView
        
        var item:Product?{
            didSet{
                if let  p = self.item{
                    self.productImageView.kf.setImage(with: URL(string: p.imageUrl))
                    self.textLabel?.text = p.name
                    self.detailTextLabel?.text = p.desc
                    self.priceLabel.text = "¥\(p.price)"
                }
            }
        }
        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            priceLabel = UILabel(frame: .zero)
            productImageView = UIImageView()
            super.init(style:style,reuseIdentifier:reuseIdentifier)
            self.steupViews()
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        func steupViews() {
            textLabel?.textColor = UIColor.hexColor(0x333333)
            detailTextLabel?.textColor = UIColor.hexColor(0x999999)
            detailTextLabel?.numberOfLines = 2
            priceLabel.textColor = UIColor.hexColor(0xe23b41)
            priceLabel.font = UIFont.systemFont(ofSize:15)
            productImageView.contentMode = .scaleAspectFit
            productImageView.clipsToBounds = true
            
            contentView.addSubview(priceLabel)
            contentView.addSubview(productImageView)
            
            productImageView.snp.makeConstraints({ make in
                make.left.equalTo(contentView).offset(20)
                make.top.equalTo(contentView).offset(10)
                make.width.equalTo(80)
                make.height.equalTo(100)
            })
            
            textLabel?.snp.makeConstraints({make in
                make.left.equalTo(productImageView.snp_right).offset(12)
                make.top.equalTo(productImageView)
                make.right.equalTo(contentView).offset(-20)
            })
            
            priceLabel.snp.makeConstraints({make in
                make.left.equalTo(textLabel!)
                make.centerY.equalTo(contentView)
            })
            detailTextLabel?.snp.makeConstraints({make in
                make.left.equalTo(textLabel!)
                make.bottom.equalTo(productImageView)
                make.right.equalTo(contentView).offset(-20)
                
                }
            )
        }
    }
    
    class ProductList: UIView,UITableViewDataSource,UITableViewDelegate {
        var tableView:UITableView
        var items:[Product] = []{
            didSet{
                self.tableView.reloadData()
            }
        }
        override init(frame: CGRect) {
              tableView = UITableView(frame: .zero,style: .plain)
                  super.init(frame: frame)
            self.setupViews()
        }
      
        func setupViews(){
            tableView.dataSource = self
            tableView.delegate = self
            tableView.tableFooterView = UIView()
            self.addSubview(tableView)
            tableView.snp.makeConstraints({make in
                make.edges.equalToSuperview()
                })
        }
        
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return items.count
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            var cell = tableView.dequeueReusableCell(withIdentifier: "cellID") as? ProductCell
            if cell == nil {
                cell = ProductCell(style: .subtitle, reuseIdentifier:  "cellID")
            }
            cell?.item = items[indexPath.row]
            return cell!
        }
        
        //高度
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return 120
        }
        
        
            
    }
    

    使用

    //
    //  HomeViewController.swift
    //  geekTime
    //
    //  Created by liuan on 2020/9/14.
    //  Copyright © 2020 liuan. All rights reserved.
    //
    
    import UIKit
    import Kingfisher
    class HomeViewController: BaseViewController,BannerViewDataSource {
        func numberOfBanner(_ bannerView: BannerView) -> Int {
            return FakeData.createBanners().count
        }
        
        func viewForBanner(_ bannerView: BannerView, index: Int, convertView: UIView?) -> UIView {
            if let view = convertView as? UIImageView{
                view.kf.setImage(with: URL(string: FakeData.createBanners()[index]))
                return view
            }else {
                let imageView = UIImageView()
                imageView.contentMode = .scaleAspectFill
                imageView.clipsToBounds = true
                imageView.kf.setImage(with: URL(string:  FakeData.createBanners()[index]))
                return imageView
            }
        }
        
    
        override func viewDidLoad() {
            super.viewDidLoad()
        
            let bannerView = BannerView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 176))
            bannerView.autoScrollInterval = 2
            bannerView.isInfinite = true
            bannerView.dataSource = self
         
            view.addSubview(bannerView)
            
            let productList = ProductList()
            productList.items = FakeData.createProducts()
            view.addSubview(productList)
            productList.snp.makeConstraints({(make) in
                make.left.right.bottom.equalToSuperview()
                make.top.equalTo(bannerView.snp_bottom).offset(5)
            } )
            
        }
        
    
    
    
    }
    

    填充

    //
    //  HomeViewController.swift
    //  geekTime
    //
    //  Created by liuan on 2020/9/14.
    //  Copyright © 2020 liuan. All rights reserved.
    //
    
    import UIKit
    import Kingfisher
    class HomeViewController: BaseViewController,BannerViewDataSource {
        func numberOfBanner(_ bannerView: BannerView) -> Int {
            return FakeData.createBanners().count
        }
        
        func viewForBanner(_ bannerView: BannerView, index: Int, convertView: UIView?) -> UIView {
            if let view = convertView as? UIImageView{
                view.kf.setImage(with: URL(string: FakeData.createBanners()[index]))
                return view
            }else {
                let imageView = UIImageView()
                imageView.contentMode = .scaleAspectFill
                imageView.clipsToBounds = true
                imageView.kf.setImage(with: URL(string:  FakeData.createBanners()[index]))
                return imageView
            }
        }
        
    
        override func viewDidLoad() {
            super.viewDidLoad()
        
            let bannerView = BannerView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 176))
            bannerView.autoScrollInterval = 2
            bannerView.isInfinite = true
            bannerView.dataSource = self
         
            view.addSubview(bannerView)
            
            let productList = ProductList()
            productList.items = FakeData.createProducts()
            view.addSubview(productList)
            productList.snp.makeConstraints({(make) in
                make.left.right.bottom.equalToSuperview()
                make.top.equalTo(bannerView.snp_bottom).offset(5)
            } )
            
        }
        
    
    
    
    }
    

     

    展开全文
  • swift5.0 原版文档

    2020-07-17 17:50:49
    TheSwiftProgrammingLanguageSwift5.epub swift5.0 原版文档
  • 前段时间听说swift5的改变之一是ABI稳定,现在看的话,swift是值得学习的,于是想通过搭建自己的博客来学习swift,顺便了解后端和mysql,以及前端页面的一些样式. 博客传送门 博客项目放在了github,喜欢的可以点赞. ...

    前段时间听说swift5的改变之一是ABI稳定,现在看的话,swift是值得学习的,于是想通过搭建自己的博客来学习swift,顺便了解后端和mysql,以及前端页面的一些样式.

    博客传送门

    博客项目放在了github,喜欢的可以点赞.

    Perfect

    在swift作为语言基础的前提下,选择了Perfect框架,Perfect网站上有详细的文档和用例,前期可以先参考Perfect-Blog-Mustache,这是一个非常简单的blog框架.Perfect文档详细介绍了每个功能模块的用法,需要注意的是HTTP路由,这是我们会经常用到的库

    云服务器和mysql

    当启动PerfectHttp服务器后,通过访问127.0.0.1:端口,就可以看到我们设置的index.html页面,通过在HTTP路由中设置的url我们可以访问对应的路径,得到对应的页面,这里的页面应该是一个静态页面,是固定不会变化的.我们可以在服务器中安装mysql作为数据提供,也可以在本机安装mysql.

    我的服务器安装了ubuntu14.0和mysql5.7,以及swift4.2.

    将项目放到github上托管,在终端使用ssh远程连接云服务器,使用git clone拉取项目,然后swift build,正常情况下会开启我们的http服务.

    这里有点要注意的,在server的路径,我们尽量使用绝对路径,我在搭建的过程中因为路径的事绕了很多圈子

    在项目中声明import PerfectMySQL,就可以连接我们的数据库,我们可以在每次访问blog文章列表的时候都读取数据库.

    同样要注意的是数据库的编码格式和字符集,不是utf8可能会导致数据库中的中文变成??

    也要注意连接数据库和ubuntu的编码,不然可能在服务器中读取不到中文

    nginx反向代理

    在我们可以通过http://ip+端口访问到我们的页面后,我们需要的可能就是一个代替ip的域名,将域名解析为我们的ip地址,但是这样只能让域名访问默认的80端口,如果我们使用的是8181端口,就需要设置nginx反向代理

    mustache页面模板

    我们的页面虽然有个数据库的支持,但是还是不能按照数据库的条数完全展示,现在我们可以利用mustache模板对前端html页面进行调整,需要在项目中引用import PerfectMustache

    buttons和bootstrap

    web页面的样式是比较复杂的,想要美观和实用,需要的时间就很多,但是有一些大神已经帮我铺好了路,造好了轮子,例如一些常见的button,在buttons上可以快速应用到我们的页面上.

    但是整个界面的布局以及在移动端上的显示,仅仅是控件还是不够的,于是我引用了bootstrap作为全段界面的主要布局,其中的栅栏布局很实用

    markdown转html的两种方案

    我们在编写文章时常用markdown格式,在Perfect里也有markdown转html的库,通过引用可以非常简单的实现转换,但是在什么时候转换,大概有两种方案:

    • 在列表中点击链接时,在网页请求时进行转换,这样可以不用生成对应的html文件
    • 提前将所有的md转化成对应的html,生成所有的html文件

    这两种方法都有各自的优缺点,选择一种就可以

    简单的shell脚本

    通过一些简单的shell和expect命令,我们在每次登陆是都可以不用输入麻烦的ip和密码操作,以及其他一些小操作

    spawn scp -r $localFile $user@$host:$targetPath
     expect "*password:"
     send "$password\r"
     interact
    复制代码

    参考

    官网例子

    Calatrava

    Swift语言开发App服务端

    Swift Perfect - 使用 systemd 命令服务器

    使用Supervisor让你的Swift服务器项目后台运行

    Swift + Perfect开发你的服务器(高级版)

    展开全文
  • C++学习视频51集完整版

    千次阅读 2015-12-03 16:16:01
    C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛。C++支持多种编程范式 --面向对象编程、泛型编程和过程化编程。最新正式标准C++于2014年8月18日公布。[1] 其编程领域众广,常用于系统开发,引擎开发...
  • Swift中 "..." 和 ".." 以及 "=="与"===

    千次阅读 2018-07-31 10:24:15
    1 “…” 和 “..” //0...5是一个闭区间[0,5] for index in 0...5 { print(index)//print &quot;012345&quot; } println(&quot;\n&quot;) //0..&amp;lt;5是一个前闭后开区间[0,5) ...0
  • 首先需要明确的一点是,什么是编译型语言和解释性语言 编译型语言,就是在其执行过程中需要先将其经过编译成机器码来给计算机识别的,其执行效率就会比较高这个是显而易见的,常见比如:C、C++ ...
  • 为何 iOS 越来越偏爱 Swift

    千次阅读 2018-10-25 00:37:45
    【CSDN编者按】本月初,苹果已经面向所有iPhone用户,推送了iOS 12.0.1正式版。那么,iOS 12.0中Swift的应用是个什么样子?iOS中使用Swift...
  • 在这里,我们手把手教你学习Xcode7和Swift2语言!重点是一看就懂,一学就会! 本篇视频教程拥有115节课程,包含数据处理、常用插件、信用卡卡号识别、自动化测试、网络访问、多线程、ShareSDK社会化分享、Core...
  • Swift快速入门(一)第一个Swift程序

    万次阅读 2016-01-23 14:58:02
    本系列只是一个Swift快速入门的教程,并没有详尽的介绍SwiftSwift也并不是一个简单的编程语言,所以要想详尽的系统的学习Swift,本系列并不适合你,此系列只是让开发者可以快速的用Swift来进行开发。另外学习本...
  • swift ~ 2020年 swift面试题

    千次阅读 2020-05-27 19:37:10
    Swift是苹果于2014年WWDC(苹果开发者大会)发布的新开发语言,可与Objective-C共同运行于MAC OS和iOS平台,用于搭建基于苹果平台的应用程序。 2、举例说明Swift里面有哪些是 Objective-C中没有的? Swift...
  • Swift初见】Swift数组

    万次阅读 2015-02-27 20:25:04
    在Objective-C中数组是常用的数据类型,在Swift中同样如此,在OC中有NSArray与NSMutableArray之分,但是在Swift中只有通过let和var来区分数组是否可变,Swift中的数组是类型安全的,所以在某个数据被存入到某个数组...
  • Swift于2015年底开源时,随之而来的最令人惊讶和最有趣的新项目之一是Swift Package Manager。虽然它不是Swift项目的第一个依赖管理器,但它是第一个由Apple正式提供和支持的,许多开发人员认为这是一个非常好的...
  • 本人最近开始学习有关Swift这个新东东,由于没有项目支撑,只能通过官方文档进行自学,精简的看了Swift官方文档,感觉理解起来还是比较简单,于是突发奇想,想把官方object-c的sample进行改造,使用Swift完成重点...
  • Swift 可选值(Optional Values)介绍

    万次阅读 热门讨论 2015-03-09 11:39:06
    Optional也是Objective-C没有的数据类型,是苹果引入到Swift语言中的全新类型,它的特点就和它的名字一样:可以有值,也可以没有值,当它没有值时,就是nil。此外,Swift的nil也和Objective-C有些不一样,在...
1 2 3 4 5 ... 20
收藏数 144,921
精华内容 57,968
关键字:

swift