说来惭愧,距上次更新笔记有一段时间了,本来计划是用两个月的时间完成本课程。结果,年前公司任务比较多,双休变单休,没能静下下心来继续学习。(PS: 都是借口,没完成就是没完成 →_→)。也罢,接下来挤时间完成余下的课程。加油,少年!
理论知识
本节课程前半部分讲解一些基本理论知识,这里只是给出罗列,不会一一讲解,如有不理解的请参考官网文档。
- Views: 说白了就是一个区域。
- Hierarchical: 一个
View
只有一个superView
,多个subViews
。
- UIWindow
- View初始化
- 坐标系统数据结构: CGFloat, CGPoint,CGSize, CGRect
- Bounds VS frame
- Creating Views
- CustomViews
- UIBezierPath使用
- NSAttributedString/NSMutableAttributedString
- Fonts
- Images
FaceDemo(画笑脸)
课程44
分钟开始讲解FaceIt
例子。本文使用的是Swift3.0
编写, 代码实现跟视频有所不同,不影响学习。
笑脸分为三个部分:
- 最外侧大圆
- 两个眼睛(两个小圆)
- 嘴巴(弧)
画圆
创建一个FaceView
,添加到ViewController
中。 在FaceView
的draw()
方法中编写。
1 2 3 4 5 6 7 8
| override func draw(_ rect: CGRect) { let skullCenter = CGPoint(x: bounds.midX, y: bounds.midY) let skullRadius = min(bounds.size.width, bounds.size.height) / 2 let path = UIBezierPath(arcCenter: skullCenter, radius: skullRadius, startAngle: 0.0, endAngle: CGFloat(2 * M_PI), clockwise: false) path.lineWidth = 5.0 UIColor.blue.set() path.stroke() }
|
效果图:
上面实现了一个圆,如果想复用,我们可以进行封装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var scale : CGFloat = 0.90 //设置比例 private var skullCenter : CGPoint { return CGPoint(x: bounds.midX, y: bounds.midY) } private var skullRadius : CGFloat { return min(bounds.size.width, bounds.size.height) / 2 * scale } private func pathForCricleCenteredAtPoint(midPoint: CGPoint, withRadius: CGFloat) -> UIBezierPath { let path = UIBezierPath(arcCenter: midPoint, radius: withRadius, startAngle: 0.0, endAngle: CGFloat(2 * M_PI), clockwise: false) path.lineWidth = 5.0 UIColor.blue.set() return path } override func draw(_ rect: CGRect) { pathForCricleCenteredAtPoint(midPoint: skullCenter, withRadius: skullRadius).stroke() }
|
画眼
下面我们来画眼睛也是圆,我们只要计算出两个圆的圆心。
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
| //结构体,定义了眼睛,嘴的预设值 private struct Ratios { static let SkullRadiusToEyeOffset: CGFloat = 3 static let SkullRadiusToEyeRadius: CGFloat = 10 static let SkullRadiusToMouthWidth: CGFloat = 1 static let SkullRadiusToMouthHeight: CGFloat = 3 static let SkullRadiusToMouthOffset: CGFloat = 3 } // 枚举: 左右眼 private enum Eye { case Left case Right } // 计算眼睛圆心 private func getEyeCenter(eye: Eye) -> CGPoint { let eyeOffset = skullRadius / Ratios.SkullRadiusToEyeOffset var eyeCenter = skullCenter eyeCenter.y -= eyeOffset switch eye { case .Left: eyeCenter.x -= eyeOffset case .Right: eyeCenter.x += eyeOffset } return eyeCenter } // 绘制眼睛 private func pathForEye(eye: Eye) -> UIBezierPath { let eyeRadius = skullRadius / Ratios.SkullRadiusToEyeRadius let eyeCenter = getEyeCenter(eye: eye) return pathForCricleCenteredAtPoint(midPoint: eyeCenter, withRadius: eyeRadius) }
|
效果图:
画嘴
下面画嘴,画一条弧线。
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
| let mouthCurvature: Double = -1.0 // 1. 笑脸,-1. 哭脸 private func pathForMouth() ->UIBezierPath { let mouthWidth = skullRadius / Ratios.SkullRadiusToMouthWidth let mouthHeight = skullRadius / Ratios.SkullRadiusToMouthHeight let mouthOffset = skullRadius / Ratios.SkullRadiusToEyeOffset let mouthRect = CGRect(x: skullCenter.x - mouthWidth / 2 , y: skullCenter.y + mouthOffset, width: mouthWidth, height: mouthHeight) //矩形区域
let smileOffset = CGFloat(max(-1, min(mouthCurvature, 1))) * mouthRect.height let start = CGPoint(x: mouthRect.minX, y: mouthRect.minY) let end = CGPoint(x: mouthRect.maxX, y: mouthRect.minY) let cp1 = CGPoint(x: mouthRect.minX + mouthRect.width / 3, y: mouthRect.minY + smileOffset) let cp2 = CGPoint(x: mouthRect.maxX - mouthRect.width / 3, y: mouthRect.minY + smileOffset) let path = UIBezierPath() path.move(to: start) path.addCurve(to: end, controlPoint1: cp1, controlPoint2: cp2) path.lineWidth = 5.0 return path }
// 最后 override func draw(_ rect: CGRect) { pathForCricleCenteredAtPoint(midPoint: skullCenter, withRadius: skullRadius).stroke() pathForEye(eye: .Left).stroke() pathForEye(eye: .Right).stroke() pathForMouth().stroke() }
|
最终效果:
更新说明
时间:2017-12-28
Stanford iOS11 with Swift