Tips


UIButton

UIButton 可以通过 currentTitle 获取当前按钮的标题,可以使用 tintColor设置主题渲染颜色

隐藏 tableView 底部多余空白 cell

tableView.tableFooterView = UIView()

时间截取

let range = str.characters.index(str.startIndex, offsetBy: 5)..<str.characters.index(str.startIndex, offsetBy: 10)
let range = str.characters.startIndex..<str.characters.index(str.startIndex, offsetBy: 10)

URL 转换成 UIImage

if let url = URL(string: "https://ssl-img.che300.com/prof_icon/home_pricing.png") {
    if let data = try? Data(contentsOf: url) {
        let image = UIImage(data: data)
    }
}

打印某个对象类型

print(type(of: str))

static 和 class 两种类型方法的区别

在 Swift 中,staticclass 这两个方法关键字都可以修饰类的方法,以表明这个方法是一个类方法,不过这两者稍微有一些区别:class 修饰的类方法可以被子类重新,而 static 修饰的类方法则不能。

导航栏和 tabbar 的按钮图片渲染

导航栏和 tabbar 按钮图片的颜色有时候显示的不是原图,原因是可能设置了全局 tintColor 对图片进行了渲染(tabbar 默认default会渲染),修改的方法是到项目中找到这个图片文件,设置render as 为 original image 就可以了

延时操作

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
    ...
}

浮点数天生是不精确的

你应该时刻记得整数和浮点数的重大差别就是浮点数天生是不精确的。

let d1 = 1.1

print("d1 + 0.1 是 \(d1 + 0.1)") // d1 + 0.1 是 1.2

if d1 + 0.1 == 1.2 {
    print("d1 + 0.1 等于 1.2")
} else {
    print("不相等") // 居然不相等
}

三目运算符

三目运算符 a ? b : c 很适合简洁的语句, 这样才优雅, 如何代码开始开始折行, 应该改用 if-esle

使用带 where 子句的 for-in 循环

// 代码比较优雅
for i in 1...100 where i % 3 == 0 {
    print(i)
}

// 如果没有 where 子句,只能使用循环并且嵌套条件语句(不优雅)
for i in 1...100 {
    if i % 3 == 0 {
        print(i)
    }
}

自动布局控件使用 UIView 动画

self.view.layoutIfNeeded() 调用 layoutIfNeeded 告知页面布局立刻更新。(系统内部调用 layoutSubviews 重写布局)

断言

assert(condition: Bool, message: String) 第一个参数是要检查的条件。如果是true什么都不会发生。如果是 false,程序就会触发陷阱并显示第二个参数提供的信息。assert(_:_:)的调用只会在 debug 模式生效,release 模式构建时候会打开一系列的编译优化并删除所有assert(_:_:)调用。如果需要再发布模式中保留断言,使用precondition(_:_:)代替。

throw

return一样,throw会让函数马上停止运行,并回到其调用者。

try 和 do/catch

  • 在一个可能抛出错误方法里面调用其他会抛出错误的方法, 可以在其内部没有 do/catch 的情况下调用 try, 如果调用失败, 错误会被再次抛出到方法外面
  • try 标记调用可能抛出错误的函数, 需要使用 do/catch 对错误进行处理
  • try! 强制处理, 一旦抛出错误那么就会触发陷阱崩溃
  • try? 可以在发生错误时候忽略而不触发陷阱, 可以用try?调用一个可能抛出的函数, 得到函数原本返回值对应的可选类型返回值. 意味着需要 guard这样的工具检查可空实例是否有值, 大多数情况避免使用, 用 catch 处理错误通常更好, 因为可以拿到函数抛出的错误. try? 最有用的情况是, 在被调用函数可能失败时还有一个后备函数可用

Swift 的错误处理哲学

Swift 的设计理念是鼓励写安全、易读的代码,它的错误处理系统也一样。任何可能失败的函数都应该用throws来标记。这样从函数类型就能明细看出是否需要处理潜在的错误。

Swift 还需要我们把所有可能失败的函数调用用try标记。这对 Swift 代码的阅读者来说极为有利。如果一个函数调用被标记为try,你就知道它是潜在的问题,必须处理。如果没有try标记,那你就知道它永远不会抛出需要处理的错误。

最后,还有一个深深植入 Swift 的重要错误处理哲学。带throws的函数不会声明自己会抛出什么样的错误。这样会产生两个实际影响:

  1. 不需要修改函数的 API 就可以随意添加潜在的 Error。
  2. 在用catch处理错误时,必须总是准备好处理未知的类型。编译器会强制保证第二点

UIView 实现渐变色

class DemoView {
    ...

    override func layoutSubviews() {
        super.layoutSubviews()
        creatGradientLayer()
    }

    func creatGradientLayer() {
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = self.bounds
        gradientLayer.colors = [UIColor(hex: 0xF8764D)!.cgColor, UIColor(hex: 0xF8A664)!.cgColor]
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
        self.layer.insertSublayer(gradientLayer, at: 0)
    }

}

正则表达式中文姓名

// 1.创建规则
let pattern = "^[\u{4e00}-\u{9fa5}·]{1,}$"
// 2.创建正则表达式对象
let pred = NSPredicate(format: "SELF MATCHES %@", pattern)
// 3.开始匹配
if pred.evaluate(with: name) {
    return true
} else {
    return false
}

JSON 格式的定义

  1. JSON 串的最外层一定是数组,对象或者值
  2. 数组由若干个对象组成,用中括号表示:[]
  3. 对象用大括号表示:{},它由键值对组成,键一定是字符串,用双引号表示 ""
  4. 值可以是 falsenulltrue、对象、数组、数字和字符串

JSON 只是一种编码规范,它仅仅规定了 JSON 格式的字符串应该具备什么特征,至于原来的数据如何转化为 JSON 串,则是由各个编程语言自己实现。一般来说,内置的基本数据类型,比如数组、字典、布尔值、字符串、数字都可以转换成 JSON 串,其中字典会转换成 JSON 中对象,用户自定义的对象一般都不能转 JSON,除非实现了特定的协议。JSON格式转换查看这个网站

results matching ""

    No results matching ""