Beginning Core Graphics(Swift)
来源:互联网 发布:windows桌面 编辑:程序博客网 时间:2024/05/21 09:44
本文内容来自于Beginning Core Graphics视频内容
Beginning Core Graphics(Swift)
Getting Started
关于drawRect(_:)
方法
- automatically called at the right time
- don’t call this method directly
- 可以通过
setNeedsDisplay()
orsetNeedsDisplayInRect()
在本例子中给NumberView.swift
自定义view,fill和stroke,最开始使用的rect是原始大小:
var lineWidth: CGFloat = 2override func drawRect(rect: CGRect) { let path = UIBezierPath(ovalInRect: rect) path.lineWidth = lineWidth UIColor.redColor().setFill() path.fill() UIColor.blueColor().setStroke() path.stroke()}
这样绘制的结果是,有部分的描边被view给裁剪掉了,如下:
这是因为a stroke is drawn half outside the line and half inside
。正确的做法是:
let insetRect = rect.insetBy(dx: lineWidth / 2, dy: lineWidth / 2) let path = UIBezierPath(ovalInRect: insetRect)
Path路径
UIBezierPath
的属性 lineCapStyle
属性
lineJoinStyle
属性
裁剪path
path.addClip()
本例是绘制一个指示器,效果如下:
使用UIBezierPath
绘制圆弧,在使用贝塞尔曲线绘制一个指针,完整代码如下:
import UIKit@IBDesignableclass SummaryView: UIView { var percentSpent:Float = 0 var lineWidth : CGFloat { return bounds.height / 4 } let margin : CGFloat = 30 let pointerLayer = CAShapeLayer() override func didMoveToSuperview() { super.didMoveToSuperview() layer.addSublayer(pointerLayer) } override func layoutSubviews() { super.layoutSubviews() let path = createPointerPath() pointerLayer.path = path.CGPath pointerLayer.fillColor = darkViewColor.CGColor pointerLayer.bounds = path.bounds pointerLayer.anchorPoint = CGPointMake(0.5, 1) pointerLayer.position = CGPointMake(bounds.midX, bounds.height - margin) } func createPointerPath() -> UIBezierPath { let pointerHeight = bounds.height - lineWidth - margin let pointerWidth: CGFloat = 18 //let pointerPath = UIBezierPath(ovalInRect: CGRectMake(0, 0, pointerWidth, pointerHeight)) let pointerPath = UIBezierPath() pointerPath.moveToPoint(CGPointMake(pointerWidth / 2, 0)) pointerPath.addCurveToPoint(CGPointMake(pointerWidth / 2, pointerHeight), controlPoint1: CGPointMake(pointerWidth / 2, 0), controlPoint2: CGPointMake(-pointerWidth, pointerHeight)) pointerPath.addCurveToPoint(CGPointMake(pointerWidth / 2, 0), controlPoint1: CGPointMake(pointerWidth * 2, pointerHeight), controlPoint2: CGPointMake(pointerWidth / 2, 0)) return pointerPath } override func drawRect(rect: CGRect) { let arcCenter = CGPointMake(rect.midX, rect.height - margin) let radius = rect.height - lineWidth / 2 - margin * 2 let startAngle : CGFloat = π let endAngle : CGFloat = 0 let path = UIBezierPath(arcCenter: arcCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true) path.lineWidth = lineWidth appGreenColor.setStroke() path.stroke() }}
关于贝塞尔曲线:
二阶贝塞尔曲线
参考:
- 我们来谈谈贝塞尔曲线
- http://cubic-bezier.com/
绘制圆弧的坐标系
在上一章的内容中绘制了一条宽为13的线,但是在iPhone6s或者iPhone6s Plus显示时,边界会有些模糊,如下:
在绘制线条时,定义起点和终点,如下绘制3个point的线
所以解决问题的关键是:
1.线宽是偶数
2.线宽是奇数,把线的位置向上或向下移动0.5个点
override func drawRect(rect: CGRect) { let path = UIBezierPath() path.lineWidth = lineWidth path.lineCapStyle = .Round path.moveToPoint(CGPoint(x: 0, y: round(rect.height/2)+0.5)) let end = rect.width * CGFloat(percent) path.addLineToPoint(CGPoint(x: end, y: round(rect.height/2)+0.5)) if percent >= 1.0 { percentDangerLineColor.setStroke() } else if percent > 0.8 { percentWarningLineColor.setStroke() } else { percentLineColor.setStroke() } path.stroke() }
context
context表示绘制的目的地
Drawing destination - view, pdf, image
- UIGraphicsBeginContextWithOptions(size:opaque:scale:)
- CGBitmapContextCreate(::::::_:)
path.addClip()
it means that all drawing outside that path is excluded.
本例是绘制一个笑脸IconFun
import UIKitvar str = "Hello, playground"let size = CGSizeMake(400, 400)let rect = CGRect(origin: .zero, size: size)let backgroundColor = UIColor.redColor()let drawingColor = UIColor.blackColor()let lineWidth : CGFloat = 5.0UIGraphicsBeginImageContextWithOptions(size, false, 0.0)let context = UIGraphicsGetCurrentContext()let edge = UIBezierPath(roundedRect: rect.insetBy(dx: lineWidth / 2, dy: lineWidth / 2), cornerRadius: 50)CGContextSaveGState(context)edge.addClip()backgroundColor.setFill()UIRectFill(rect)CGContextRestoreGState(context)edge.lineWidth = lineWidthdrawingColor.setStroke()edge.stroke()let outerCircle = UIBezierPath(ovalInRect: CGRect(x: 46, y: 46, width: 310, height: 310))outerCircle.lineWidth = lineWidthouterCircle.stroke()let eye1 = UIBezierPath(ovalInRect: CGRect(x: 138, y: 126, width: 36, height: 72))eye1.lineWidth = lineWidtheye1.stroke()let eye2 = UIBezierPath(ovalInRect: CGRect(x: 223, y: 126, width: 36, height: 72))eye2.lineWidth = lineWidtheye2.stroke()let mouth = UIBezierPath()mouth.lineWidth = lineWidthmouth.moveToPoint(CGPointMake(136, 250))mouth.addLineToPoint(CGPointMake(265, 250))mouth.addCurveToPoint(CGPointMake(135, 250), controlPoint1: CGPoint(x:240, y:300), controlPoint2: CGPoint(x: 150, y: 300))mouth.closePath()mouth.lineJoinStyle = .Roundmouth.stroke()let path = UIBezierPath()path.appendPath(outerCircle)path.appendPath(eye1)path.appendPath(eye2)path.appendPath(mouth)let image = UIGraphicsGetImageFromCurrentImageContext()UIGraphicsEndImageContext()imageUIGraphicsBeginImageContextWithOptions(size, false, 0.0)path.stroke()let image2 = UIGraphicsGetImageFromCurrentImageContext()UIGraphicsEndImageContext()
效果如下:
使用Core Graphic
来绘制
Device
的坐标系原点在左上角,Core Graphic
坐标系原点在右下角。当使用UI graphics context时,context会自动被翻转,所以所有的CGContext命令都会从左上角绘制。
然而当你使用CGBitmapContextCreate
创建context时,坐标系原点是在右下角。
使用image.drawInRect(_:)
绘制图片,图片会在指定的rect绘制。
但使用CGContextDrawImage(_:_:_:)
绘制图片,图片会被翻转。
给path应用变换path.applyTransform(_:)
,例如,移动、缩放、旋转
本例是个path应用变换:
private func scalePath(path:UIBezierPath, size:CGSize) { // scale path - icons should all be same height let scale = size.height / path.bounds.size.height * 0.5 path.applyTransform(CGAffineTransformMakeScale(scale, scale)) // move path to origin path.applyTransform(CGAffineTransformMakeTranslation(-path.bounds.origin.x, -path.bounds.origin.y)) // move path into center path.applyTransform(CGAffineTransformMakeTranslation(size.width/2 - path.bounds.width/2, size.height/2 - path.bounds.height/2)) }
PaintCode
使用PaintCode软件来绘制
- Beginning Core Graphics(Swift)
- Intermediate Core Graphics(Swift)一
- Intermediate Core Graphics(Swift)二
- Intermediate Core Graphics(Swift)三
- Swift Core Graphics教程之Gradients 与 Context
- Swift- Core Graphics绘图框架详解2(绘制图形)
- Core Graphics
- Core Graphics
- Core Graphics
- Core Graphics
- Core Graphics
- core graphics
- Core Graphics
- Core Graphics
- Core Graphics
- core Graphics
- Core Graphics
- Swift-Core Graphics绘图框架详解3(绘制渐变、填充渐变色)
- quick-cocos UIInput字数过多崩溃问题
- json和xml传输的区别
- DHCP详解
- 【 第16周项目1-冒泡排序】
- js解决window.open 被IE弹出窗口阻止程序拦截
- Beginning Core Graphics(Swift)
- C++中 const(百度百科)
- Android 定时器的三种实现方法
- maven 概念与实践 phase, goal, plugin
- 第十六周 项目3-归并排序算法的改进
- 记一次网络能ping通,但浏览器不能访问网页的遭遇
- Thrift源码系列----3.TProtocol层功能分析
- 第十五周项目2--用哈希法组织关键字
- 如何关闭squid的缓存功能