异常处理
声明可以抛出异常的函数
// 无返回值
func save() throws
// 有返回值
func save() throws -> Bool
捕获异常方式
do {
try context.save()
} catch let error {
// error will be something that implements the Error protocol, e.g., NSError
// usually these are enums that have associated values to get error details
throw error // this would re-throw the error (only ok if the method we are in throws)
}
try! 用来表示确信不会抛出异常,如果抛出异常,程序将crash
try! context.save() // will crash your program if save() actually throws an error
try? 条件测试,返回值为optional类型。如果抛出异常,try?后面的语句返回nil,否则正常返回。
let x = try? errorProneFunctionThatReturnsAnInt() // x will be Int?
Any & AnyObject
Swift是强类型语言,应尽量避免使用Any。
在初始化NSAttributedString时,使用Any表示属性字典的value可以是任意类型的对象。
let attributes: [NSAttributedStringKey:Any] = ...
有时函数参数里也会有Any出现,表示任意类型的对象
func prepare(for segue: UIStoryboardSegue, sender: Any?)
使用as?用来确定具体类型
// ConcentrationViewController是UIViewController的子类
// ConcentrationViewController包含方法flipCard
let vc: UIViewController = ConcentrationViewController()
if let cvc = vc as? ConcentrationViewController {
cvc.flipCard(...) // this is okay
}
View的坐标系
坐标系原点:左上角
bounds:描述相对于view自身坐标系内的位置和尺寸
frame:描述view相对于父view坐标系下的位置和尺寸
center:view的中心点在父view坐标系下的位置
view在未旋转前bounds.size等于frame.size,旋转后二者的关系将发生变化。下图中
View B’s bounds = ((0,0),(200,250))
View B’s frame = ((140,65),(320,320))
View B’s center = (300,225)
View B中心点在自身坐标系下的位置为(bounds.midX, bounds.midY) = (100,125)
绘制View
方法:创建UIView的子view,重写draw方法
override func draw(_ rect: CGRect)
触发系统重新绘制需调用下面方法,不能直接调用draw(CGRect)。
setNeedsDisplay()
setNeedsDisplay(_ rect: CGRect) // rect is the area that needs to be redrawn
Core Graphics绘图步
绘图步骤:
1.初始化画布
UIGraphicsGetCurrentContext()
2.创建路径:
let path = UIBezierPath()
path.move(to: CGPoint(80, 50))
path.addLine(to: CGPoint(140, 150))
path.addLine(to: CGPoint(10, 150))
3.添加绘制属性,如颜色、字体、线宽等
UIColor.green.setFill() // note setFill is a method in UIColor, not UIBezierPath
UIColor.red.setStroke() // note setStroke is a method in UIColor, not UIBezierPath
path.linewidth = 3.0 // linewidth is a property in UIBezierPath, not UIColor
4.填充或描边上面创建路径
path.fill() // fill is a method in UIBezierPath
path.stroke() // stroke method in UIBezierPath
绘制Text
可以使用NSAttributedString控制字符串中字符的绘制属性,NSRange即可以处理NSString的范围,又可以处理String的范围
let pizzaJoint = “café pesto”
var attrString = NSMutableAttributedString(string: pizzaJoint)
let firstWordRange = pizzaJoint.startIndex..<pizzaJoint.indexOf(“ “)!
let nsrange = NSRange(firstWordRange, in: pizzaJoint) // convert Range<String.Index>
attrString.addAttribute(.strokeColor, value: UIColor.orange, range: nsrange)
字体
获取系统推荐的字体
//UIFontTextStyle.headline
// .body
// .footnote
static func preferredFont(forTextStyle: UIFontTextStyle) -> UIFont
通过字体名字初始化
let font = UIFont(name: “Helvetica”, size: 36.0)
使用metrics设置想要的字体,同时用户可以在系统设置中调节字体大小
let metrics = UIFontMetrics(forTextStyle: .body) // or UIFontMetrics.default let
fontToUse = metrics.scaledFont(for: font)
绘制图
系统提供将图从某一点绘制,在某个区域绘制,以某一模式平铺绘制。具体方法如下
let image: UIImage = ...
image.draw(at point: aCGPoint) // the upper left corner put at aCGPoint
image.draw(in rect: aCGRect) // scales the image to fit aCGRect
image.drawAsPattern(in rect: aCGRect) // tiles the image into aCGRect
UIViewContentMode
UIView的bounds变化时,可以根据UIView.contentMode来自动调整view中内容的绘制方式
只移位时可使用
.left/.right/.top/.bottom/.topRight/.topLeft/.bottomRight/.bottomLeft/.center
有缩放时可使用
.scaleToFill/.scaleAspectFill/.scaleAspectFit // .scaleToFill is the default
触发重画可使用
.redraw
这些类型对应的效果可参考文章UIViewContentMode。
LayoutSubviews
View的bounds变化时,可以通过在当前view中重写当前layoutSubviews方法,调整子view的位置。
override func layoutSubviews() {
super.layoutSubviews()
// reposition my subviews’s frames based on my new bounds
}