I'm new to swift and I currently follow screencasts from CS193P. In one episode, It show me to create smiley face using drawRect. I tried to replicate it but it's turn out It's doesn't work very well. In Original Screencast, it turn out to as well blown smiley face but In my exercise, mine is turn out to as follows;
It seem work on landscape mode though.
My Code is as follows and could you please guide me which parts is wrong ???
import UIKit
class FaceView: UIView {
var faceCenter: CGPoint {
return convertPoint(center, fromView:superview)
}
var scale:CGFloat {
return 0.9
}
private struct Scaling {
static let FaceRadiusToEyeRadiusRatio: CGFloat = 10
static let FaceRadiusToEyeOffsetRatio: CGFloat = 3
static let FaceRadiusToEyeSeperationRatio: 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.FaceRadiusToEyeSeperationRatio
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
}
var faceRadius: CGFloat {
return min(bounds.size.width,bounds.size.height) / 2 * scale
}
var lineWidth: CGFloat = 3 { didSet { setNeedsDisplay() } }
var color: UIColor = UIColor.blueColor() { didSet { setNeedsDisplay() } }
override func drawRect(rect: CGRect) {
let facePath = UIBezierPath(arcCenter: faceCenter, radius: faceRadius, startAngle: 0, endAngle: CGFloat(2*M_PI), clockwise: true)
facePath.lineWidth = 3
color.set()
facePath.stroke()
bezierPathForEye(.Left).stroke()
bezierPathForEye(.Right).stroke()
let smiliness = 0.75
let smilepath = bezierPathForSmile(smiliness)
smilepath.stroke()
}
}
FYI, That's not an assignment and I just trying to replicate things for exercising.
Change from
eyeCenter.y = eyeVerticalOffset
into this
eyeCenter.y -= eyeVerticalOffset