1. Objective-C 兼容性 Bridging
Swift 可以无缝使用以前 Objective-C 的 API,但是一些特殊的数据类型需要桥接。桥接是指可以互换的使用。
NSString <-> String
NSArray <-> Array
NSDictionary <-> Dictionary<NSObject, AnyObject>
Int, Float, Double, Bool -> NSNumber (反之不行)
99%的桥接均是隐式完成的。
2. 属性列表 属性列表指 AnyObject 是一下六种类型的集合列表: NSString, NSArray, NSDictionary, NSNumber, NSData, NSDate。
处理属性列表通常需要映射:如 is 和 as。
属性列表可以“盲”传递数据,也可以作为一种通用数据结构-类似泛型。
NSUserDefaults 作为一种使用属性列表的存储机制。本质上就是一个小的存储数据列表的数据库。通常用存储“设置”信息。 NSUserDefaults 可以通过名称或键来存储或检索整个属性列表。
以下用法摘自:NSUserDefaults — A Swift Introduction
存储 NSUserDefaults 1 2 let defaults = NSUserDefaults.standardUserDefaults() defaults.setObject("Coding Explorer", forKey: "userNameKey")
NSUserDefaults 常用的写入方法:
func setBool(value: Bool, forKey defaultName: String)
func setInteger(value: Int, forKey defaultName: String)
func setFloat(value: Float, forKey defaultName: String)
func setDouble(value: Double, forKey defaultName: String)
func setObject(value: AnyObject?, forKey defaultName: String)
func setURL(url: NSURL, forKey defaultName: String)
iOS 8或更新版本不要使用 synchronize。
读取 NSUserDefaults 1 2 3 4 5 let defaults = NSUserDefaults.standardUserDefaults() if let name = defaults.stringForKey("userNameKey") { println(name) }
对应的常用读取 NSUserDefaults 的方法:
func boolForKey(defaultName: String) -> Bool
func integerForKey(defaultName: String) -> Int
func floatForKey(defaultName: String) -> Float
func doubleForKey(defaultName: String) -> Double
func objectForKey(defaultName: String) -> AnyObject?
func URLForKey(defaultName: String) -> NSURL?
func dataForKey(defaultName: String) -> NSData?
func stringForKey(defaultName: String) -> String?
func stringArrayForKey(defaultName: String) -> [AnyObject]?
func arrayForKey(defaultName: String) -> [AnyObject]?
func dictionaryForKey(defaultName: String) -> [NSObject : AnyObject]?
使用常量做键 方便在一处修改,容易理解编译报错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 let userNameKeyConstant = "userNameKey" @IBAction func writeButton(sender: UIButton) { let defaults = NSUserDefaults.standardUserDefaults() defaults.setObject("Coding Explorer", forKey: userNameKeyConstant) } @IBAction func readButton(sender: UIButton) { let defaults = NSUserDefaults.standardUserDefaults() if let name = defaults.stringForKey(userNameKeyConstant) { print(name) } }
3. 视图 视图代表了一个长方形区域。
视图是等级,类似单继承:一个视图只可以有一个 superview,但可以有很多 subviews。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 // // FaceView.swift // Happiness // // Created by Will Ge on 7/17/15. // Copyright © 2015 gewill.org. All rights reserved. // import UIKit class FaceView: UIView { var lineWidth: CGFloat = 5 { didSet { setNeedsDisplay() } } var color: UIColor = UIColor.blueColor() { didSet { setNeedsDisplay() } } var scale: CGFloat = 0.9 var faceCenter: CGPoint { return convertPoint(center, fromView: superview) } var faceRadius: CGFloat { return min(bounds.size.width, bounds.size.height) / 2 * scale } // 覆写 drawRect,自定义视图 override func drawRect(rect: CGRect) { // 画脸 let facePath = UIBezierPath(arcCenter: faceCenter, radius: faceRadius, startAngle: 0, endAngle: CGFloat(2 * M_PI), clockwise: true) facePath.lineWidth = lineWidth color.set() facePath.stroke() // 画眼 bezierPathForEye(.Left).stroke() bezierPathForEye(.Right).stroke() // 画嘴巴 let smiliness = 0.8 let smilePath = bezierPathForSmile(smiliness) smilePath.stroke() } private struct Scaling { static let FaceRadiusToEyeRadiusRatio: CGFloat = 10 static let FaceRadiusToEyeOffsetRatio: CGFloat = 3 static let FaceRadiusToEyeSeparationRatio: CGFloat = 1.5 static let FaceRadiusToMouthWidthRatio: CGFloat = 1 static let FaceRadiusToMouthHeightRatio: CGFloat = 3 static let FaceRadiusToMouthOffsetRatio: CGFloat = 3 } // 定义枚举:左右眼 private enum Eye { case Left, Right } // 定义函数:眼睛的路径 private func bezierPathForEye(whichEye: Eye) -> UIBezierPath { let eyeRadius = faceRadius / Scaling.FaceRadiusToEyeRadiusRatio let eyeVerticalOffset = faceRadius / Scaling.FaceRadiusToEyeOffsetRatio let eyeHorizontalSeparation = faceRadius / Scaling.FaceRadiusToEyeSeparationRatio var eyeCenter = faceCenter eyeCenter.y -= eyeVerticalOffset switch whichEye { case .Left: eyeCenter.x -= eyeHorizontalSeparation / 2 case .Right: eyeCenter.x += eyeHorizontalSeparation / 2 } let path = UIBezierPath(arcCenter: eyeCenter, radius: eyeRadius, startAngle: 0, endAngle: CGFloat(2 * M_PI), clockwise: true) path.lineWidth = lineWidth return path } // 定义函数:嘴巴的路径 private func bezierPathForSmile(fractionOfMaxSmile: Double) -> UIBezierPath { let mouthWidth = faceRadius / Scaling.FaceRadiusToMouthWidthRatio let mouthHeight = faceRadius / Scaling.FaceRadiusToMouthHeightRatio let mouthVerticalOffset = faceRadius / Scaling.FaceRadiusToMouthOffsetRatio let smileHeight = CGFloat(max(min(fractionOfMaxSmile, 1), -1)) * mouthHeight let start = CGPoint(x: faceCenter.x - mouthWidth / 2, y: faceCenter.y + mouthVerticalOffset) let end = CGPoint(x: start.x + mouthWidth, y: start.y) let cp1 = CGPoint(x: start.x + mouthWidth / 3, y: start.y + smileHeight) let cp2 = CGPoint(x: end.x - mouthWidth / 3, y: cp1.y) let path = UIBezierPath() path.moveToPoint(start) path.addCurveToPoint(end, controlPoint1: cp1, controlPoint2: cp2) path.lineWidth = lineWidth return path } }