Swift3.0 利用泛型设置基类属性的动态类型

Swift3.0 利用泛型设置基类属性的动态类型
2017/05/25 posted in  iOS

基于BarrageRender自定义弹幕动画

[BarrageRender](https://github.com/unash/BarrageRenderer) 是iOS上一个非常出名的弹幕渲染开源框架,其可以让我们在App中非常方便的集成弹幕功能,其作者在代码中提供了两种方式的弹幕动画,`BarrageFloatSprite`和`BarrageWalkSprite`。可以说移动和浮动这两种动画方式基本上已经满足了大部分App的需求,但是仍然有部分App需要在弹幕的展现形式上更加的自由,例如各大直播平台的礼物弹幕。笔者将在这篇文章中分享自己在BarrageRender的基础上编写自定义礼物弹幕的过程
2017/05/19 posted in  iOS

Swift要点

(本文所有代码样例全部来自Swift2.0官方文档)

  1. Swift类型间不会隐式转换,必须要显式转换。将值转换成字符串除了使用String()显式转换外,还有中简单的方法,如下:

    let apples = 3
    let oranges = 5
    let appleSummary = "I have \(apples) apples."
    let fruitSummary = "I have \(apples + oranges) pieces of fruit."

    输出:

    "I have 3 apples"
    "I have 8 pieces of fruit"
    
  2. Swift声明数组或者字典可以声明指定类型

    let emptyArray = [String]()
    let emptyDictionary = [String: Float]()
    
  3. if语句中,条件必须是一个布尔表达式,如下:

     if score > 50 {
        teamScore += 3
    } else {
    teamScore += 1
    }

    if 1 {} 这样代码会报错,但是if true{}这样的代码是可 以的。

  4. Switch 支持任意类型的数据以及各种比较,不仅仅限于整数以及判断是否相等,而且Switch匹配到相应的子句之后就会推出整个Switch,不需要给每个Switch子句写上break了。

    let vegetable = "red pepper"
    switch vegetable {
    case "celery":
    print("Add some raisins and make ants on a log.")
    case "cucumber", "watercress":
    print("That would make a good tea sandwich.")
    case let x where x.hasSuffix("pepper"):
    print("Is it a spicy \(x)?")
    default:
    print("Everything tastes good in soup.")
    }

    Swift 子句中必须要遍历所有可能,否则会报错
    上述代码中的lex表达式将匹配等式的值赋给变量x

  5. do{}while()被repeat{}while()取代

    var m = 2
    repeat {
    m = m * 2
    } while m < 100
    print(m)
  6. 循环有更简便的写法,0..<4表示遍历0到4(不包含4,包含4用0...4),传统写法也是支持的。

    var firstForLoop = 0
    for i in 0..<4 {
    firstForLoop += i
    }
    print(firstForLoop)
    var firstForLoop = 0
    for i in 0...4 {
    firstForLoop += i
    }
    print(firstForLoop)
  7. 函数可以传入可变的参数,参数在函数内表现为数组形式:

    func sumOf(numbers: Int...) -> Int {
    var sum = 0
    for number in numbers {
    sum += number
    }
    return sum
    }
    sumOf()
    sumOf(42, 597, 12)
  8. 函数可以作为另一个函数的返回值,类似于OC中的block

    func makeIncrementer() -> (Int -> Int) {
    func addOne(number: Int) -> Int {
    return 1 + number
    }
    return addOne
    }
    var increment = makeIncrementer()
    increment(7)

    同理,函数也可以当做参数传入函数,

    func hasAnyMatches(list: [Int], condition: Int ->   Bool) -> Bool {
    for item in list {
    if condition(item) {
    return true
    }
    }
    return false
    }
    func lessThanTen(number: Int) -> Bool {
    return number < 10
    }
    var numbers = [20, 19, 7, 12]
    hasAnyMatches(numbers, condition: lessThanTen)
  9. 子类中,如果需要重写父类的方法,需要使用override标记

    class NamedShape {
    var numberOfSides: Int = 0
    var name: String
    init(name: String) {
    self.name = name
    }
    func simpleDescription() -> String {
    return "A shape with \(numberOfSides) sides."
    }
    }
    class Square: NamedShape {
    var sideLength: Double
    init(sideLength: Double, name: String) {
    self.sideLength = sideLength
    super.init(name: name)
    numberOfSides = 4
    }
    func area() -> Double {
    return sideLength * sideLength
    }
    override func simpleDescription() -> String {
    return "A square with sides of length \(sideLength)."
    }
    }
    let test = Square(sideLength: 5.2, name: "my test square")
    test.area()
    test.simpleDescription()
2016/10/11 posted in  iOS

Swift学习要点-基础部分

2016-06-29_15:09:33.jpg

这一系列的文章都是我本人在学习Swift语法过程中认为需要注意的语法部分,所以介绍的并不会很完整。

  1. print函数:print(_:separator:terminator:),默认情况下print会以换行符当做结束符,此外你可以通过terminator参数更改结束符,例如:

    print("正常的print结尾时换行符")                  //输出:正常的print结尾时换行符\n
    print("没有换行符的print",terminator:"")         //输出:没有换行符的print
    print("稀奇古怪的结束符都可以",terminator:"(^^)") //输出:稀奇古怪的结束符都可以(^^)
  2. 数值类字面量,包括整数和浮点数可以添加额外的零并且包含下划线,并不会影响字面量的值

    let paddedDouble = 000123.456
    let oneMillion = 1_000_000
    let justOverOneMillion = 1_000_000.000_000_1
  3. 可以通过typealias关键字来定义类型的别名

    typealias AudioSample = UInt16
    var maxAmplitudeFound = AudioSample.min // maxAmplitudeFound 现在是 0
    
  4. 不同的数据类型之间不会隐式转换,必须要用类型名加上括号的方式进入显示转换,其中显示转换成字符串除了使用String()之外,还可以直接在字符串中适用(其他类型值)来转换

    var maxValue = UInt8.max
    var max64Value = Int64.max
    max64Value = maxValue //Error:Cannot assign value of type 'UInt8' to type 'Int64'
    max64Value = Int64(maxValue) //Ok
    let number = 3
    var str1 = String(number) //str1 = "3"
    var str2 = "\(number)" //str2 = "3"
  5. 如果你只需要一部分元组值,分解的时候可以把要忽略的部分用下划线(_)标记:

    let http404Error = (404, "Not Found")  // http404Error 的类型是 (Int, String),值是 (404, "Not Found")
    let (justTheStatusCode, _) = http404Error
    print("The status code is \(justTheStatusCode)") // 输出 "The status code is 404"
  6. Swift 的nil和 Objective-C 中的nil并不一样。在 Objective-C 中,nil是一个指向不存在对象的指针。在 Swift 中,nil不是指针——它是一个确定的值,用来表示值缺失。任何类型的可选状态都可以被设置为nil,不只是对象类型。

    var serverResponseCode: Int? = 404
    // serverResponseCode 包含一个可选的 Int 值 404
    serverResponseCode = nil
    // serverResponseCode 现在不包含值
  7. 使用!来强制解析值之前,一定要确定可选包含一个非nil的值,否则当强制解析一个nil值时会报错。

    var option:Int?    //没有初始值的可选类型变量默认值为nil
    var str = "\(option)" //输出:"nil"
    str = "\(option!)" //Error
  8. 常量的值一旦被确定就不能修改,但是用let声明常量时可以不必紧跟其后为其设置初始值。

    let const_a:String
    if (condition){
    const_a = "a"
    }else{
    const_a = "b"
    }
2016/10/11 posted in  iOS

CocoaPods master仓库替换为国内源

2016-06-29_1396084357114.jpg
国内用CocoaPods 实在是太蛋疼了,一个pod update都要等好久,之前唐巧博客里面推荐的那个国内源已经不可用了,还好今天在V2EX上看到有人提供了别的CocoaPods源。

  1. https://git.coding.net/hging/Specs.git
  2. http://git.oschina.net/akuandev/Specs

执行如下命令替换Pods源

$ pod repo remove master
$ pod repo add master 'http://git.oschina.net/akuandev/Specs.git' 


仅仅这样使用pod update时发现仍然会从一个master-1这个官方源中clone

tianxianggendeMacBook-Air:upyun-batch-upload mylonly$ pod install
Creating shallow clone of spec repo `master-1` from `https://github.com/CocoaPods/Specs.git`


这时候需要在Podfile中加入source命令,就可以直接从国内源更新了。

source 'http://git.oschina.net/akuandev/Specs.git'
platform :ios, '6.0'
pod 'AFNetworking', '~> 1.3.4'
2016/05/11 posted in  iOS