- iOS上主要的绘图技术有:UIKit、Quartz 2D、Core Animation和OpenGL ES。
- UIView绘制方法主要是drawRect:方法,还有setNeedsDisplay和setNeedsDisplayInRect:方法。
- 触发视图重绘的动作有以下几种:
(1)当遮挡视图的其他视图被移动或删除操作时。
(2)将视图的hidden属性声明设置为false,使其从隐藏状态变为可见。
(3)将视图滚出屏幕,然后再重新回到屏幕上。
(4)显示调用视图的setNeedsDisplay或者setNeedsDisplayInRect:方法。
UIKit填充、描边、绘制图形、绘制文本:
override func draw(_ rect: CGRect) {
// 填充矩形
UIColor.brown.setFill()
UIRectFill(rect)
// 描边
UIColor.white.setStroke()
let frame = CGRect.init(x: 20, y: 30, width: 100, height: 300)
UIRectFrame(frame)
// 绘制图像
let imagePath = Bundle.main.path(forResource: "zcm", ofType: "png")
let myImageObj: UIImage = UIImage.init(contentsOfFile: imagePath!)!
myImageObj.draw(in: CGRect.init(x: 150, y: 30, width: 100, height: 100))
myImageObj.draw(in: CGRect.init(x: 250, y: 30, width: 100, height: 100))
myImageObj.draw(in: CGRect.init(x: 350, y: 30, width: 100, height: 100))
// 绘制文本
let title: NSString = "招财猫"
let font: UIFont = UIFont.systemFont(ofSize: 34)
let attr = [NSFontAttributeName: font]
title.draw(at: CGPoint.init(x: 150, y: 150), withAttributes: attr)
}
显示结果如下:
Quartz路径:
override func draw(_ rect: CGRect) {
// 获得访问图形上下文对象
let context = UIGraphicsGetCurrentContext()
// --- 填充三角形
// 1. 移动某个点
context?.move(to: CGPoint.init(x: 75, y: 200))
// 2. 添加路径
context?.addLine(to: CGPoint.init(x: 10, y: 150))
context?.addLine(to: CGPoint.init(x: 160, y: 150))
// 3. 关闭路径
context?.closePath()
// 设置黑色描边参数
UIColor.black.setStroke()
// 设置红色填充参数
UIColor.green.setFill()
context?.saveGState()
UIColor.red.setFill()
// 将之前保留的内容恢复出来
context?.restoreGState()
// 绘制路径
context?.drawPath(using: CGPathDrawingMode.fillStroke)
// --- 经典花瓶侧面(贝塞尔曲线)
/**
context?.addCurve(to: ,// 结束点坐标,
control1: , // 第一控制点坐标
control2: ) // 第二控制的坐标
*/
context?.move(to: CGPoint.init(x: 333, y: 0))
context?.addCurve(to: CGPoint.init(x: 330, y: 26), control1: CGPoint.init(x: 333, y: 0), control2: CGPoint.init(x: 332, y: 26))
context?.addCurve(to: CGPoint.init(x: 299, y: 17), control1: CGPoint.init(x: 330, y: 26), control2: CGPoint.init(x: 299, y: 20))
context?.addLine(to: CGPoint.init(x: 296, y: 17))
context?.addCurve(to: CGPoint.init(x: 291, y: 19), control1: CGPoint.init(x: 296, y: 17), control2: CGPoint.init(x: 296, y: 19))
context?.addLine(to: CGPoint.init(x: 250, y: 19))
context?.addCurve(to: CGPoint.init(x: 238, y: 19), control1: CGPoint.init(x: 250, y: 19), control2: CGPoint.init(x: 241, y: 24))
context?.addCurve(to: CGPoint.init(x: 227, y: 24), control1: CGPoint.init(x: 236, y: 20), control2: CGPoint.init(x: 234, y: 24))
context?.addCurve(to: CGPoint.init(x: 216, y: 19), control1: CGPoint.init(x: 220, y: 24), control2: CGPoint.init(x: 217, y: 19))
context?.addCurve(to: CGPoint.init(x: 207, y: 20), control1: CGPoint.init(x: 214, y: 20), control2: CGPoint.init(x: 211, y: 22))
context?.addCurve(to: CGPoint.init(x: 182, y: 21), control1: CGPoint.init(x: 207, y: 20), control2: CGPoint.init(x: 187, y: 20))
context?.addLine(to: CGPoint.init(x: 100, y: 45))
context?.addLine(to: CGPoint.init(x: 97, y: 46))
context?.addCurve(to: CGPoint.init(x: 64, y: 72), control1: CGPoint.init(x: 97, y: 46), control2: CGPoint.init(x: 86, y: 71))
context?.addCurve(to: CGPoint.init(x: 23, y: 48), control1: CGPoint.init(x: 42, y: 74), control2: CGPoint.init(x: 26, y: 56))
context?.addLine(to: CGPoint.init(x: 9, y: 47))
context?.addCurve(to: CGPoint.init(x: 0, y: 0), control1: CGPoint.init(x: 9, y: 47), control2: CGPoint.init(x: 0, y: 31))
context?.strokePath()
}
显示结果:
Quartz坐标系相关:
override func draw(_ rect: CGRect) {
/*
// Quartz 2D坐标系,原点在左下角,x轴方向向右为正方向,y轴方向向上为正方向
//
// UIKit坐标系,原点在左上角,x轴方向向右为正方向,y轴方向向下为正方向
//
*/
let path = Bundle.main.path(forResource: "zcm", ofType: "png")
let img: UIImage = UIImage.init(contentsOfFile: path!)!
let image: CGImage = img.cgImage!
let context = UIGraphicsGetCurrentContext()
context?.saveGState()
let touchRect = CGRect.init(x: 0, y: 0, width: img.size.width/2, height: img.size.height/2)
context?.draw(image, in: touchRect)
context?.restoreGState()
// 正常图片显示
context?.saveGState()
context?.translateBy(x: 0, y: img.size.height)
context?.scaleBy(x: 1, y: -1)
context?.draw(image, in: touchRect)
context?.restoreGState()
}
显示结果: