编辑代码

//
//ViewContro_ler.swift
//GraphDemo
//Created by
//Copyright Zhifeng Chen on 2020/8/4.
//Copyright 2020 Zhifeng Chen. Al1 rights reserved.
//

import UIKit

class CoreGraphUIView: UIView {
  override func touchesBegan(_touches:Set<UITouch>, with event: UIEvent?) {
  self.backgroundColor = UIColor.red
   print("Began:\(touches)")
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.backgroundColor = UIColor.lightGray
print("Ended:\(touches)")
override func touchesMoved(_touches: Set<UITouch>, with event: UIEvent?)
self.backgroundColor= UIColor.blue
print("Moved:\(touches)")
class ViewController: UIViewController {
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
 let height = self.view.frame.size,height
let width = self.view.frame.size,width
let graphFrame = CGRect(x: 0, y: 0, width: width, height: height) 
let graphView = CoreGraphUIView(frame: graphFrame)
graphView.backgroundColor = UIColor.white
self.view.addSubview(graphView)
}
}
let touch:UITouch = touches.first! as UITouch
print (touch.location(in: view).x)
print(touch.location(in: view).y)
classShape 组建平面图形乐队 
//名称
var name :String?
// 边数
varsides:Int?
//左上角的位置坐标
var origin : CGPoint?
//线条颜色
var lineColor: UIColor = UIColor.red
//填充颜色
var fillColor:UIColor = UIColor.green
// 线条宽度
var lineWidth : CGFloat =2
//构造器函数init
init (name : String, sides : Int, origin : CGPoint)f
self.name = name
self.sides = sides
self.origin = origin
// 自定义方法 sayHe1lo
func sayHello()t
print("Shape is \(name!),sides \(sides!), and originCord is(\(oriqin!.x),\(origin!.y))")
}
}

//
//ViewController.swift
//ShapeDemo
//
//Created by Zhifeng Chen on 2020/8/4.
//Copyright  2020 Zhifeng Chen. All rights reserved.

import UIKit
class Shape {
//名称
var name :String?
//边数
varsides:Int?
//左上角的位置坐标
var origin: CGPoint?
//线条颜色
varlineColor: UIColor = UIColor.red
//填充颜色
var fillColor : UIColor = UIColor.green
// 线条宽度
var lineWidth: CGFloat=2
//构造器函数init
init (name: String, sides : Int, origin: CGPoint)
self.name - name
self.sides = sides
self.origin = origin
)
//自定义方法sayHe1lo
func sayHello()(
print("Shape is\(name!), sides \(sides!), and originCord is((origin!.x),\(origin!.y))")
class ViewController: UIViewController 一
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
//此处调用Shape类,建立一个对象(实例)myShaple
let myShape =Shape (name:"BaseShape", sides: 0, origin: CGPoint(x:0, y: 0))
my Shape.sayHel1o()
}
}
ViewController.swift
DrawMusic
Created by Zhifeng Chen on 2020/8/4.
Copyright 2020Zhifeng Chen. A11 rights reserved.
import UIKit
class Shape 
//名称
var name :String?
//边数
var sides :Int?
//左上角的位置坐标
var origin : CGPoint?
//线条颜色
var lineColor :UIColor = UIColor.red
//填充颜色
var fillColor:UIColor= UIColor.green
//线条宽度
var lineWidth : CGFloat - 2
//构造器函数init
init(name : String, sides : Int, origin: CGPoint)
self.name = name
self.sides = sides
self.origin = origin
//自定义方法sayHello
func sayHello()(
print("Shape:\(name!),sides\(sides!), origin (\(origin!.x),
(origin!.y)) ")
CzfView: UIView
[
//成员变量(属性)shape,其类型为Shape
class
var shape : Shape?
// 重载 UIView的draw方法
override func drawi rect: CGRect)(
//判断shape变量是否为空值n11
guard let = shape else(
xeturn
1
//不为空,则调用shape这个实例的方法
s.sayHello()
classViewController:UIViewController
override func viewDidLoad() t
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//此处调用Shape类,建立一个对象(实例)myShape
let myShape = Shape(name:"BaseShape", sides: 0, origin: CGPoint(x:
0, y: 0))
//此处建立了一个CzfView的实例myView
let width = self.view.frame.size.width
let height = self.view.frame.size.height
let myView = CzfView(frame: CGRect(x: 0, y: 0,width: width height: height))
//赋值给myView中的成员变量(属性) shape
myView. shape = myShape
/ / 显示 myView
self.view.addSubview(myView)
}
}
classLine : Shape [
//线段的起点
var start : CGPoint?
//线段的终点
var end :CGPoint?
//构造器
init(name: String, origin: CGPoint, start: CGPoint, end : CGPoint)
super.init(name: name, origin: origin)
self.start = start
self.end = end
convenience init(start : CGPoint, end : CGPoint)
self.init (name: "Line", origin: start, start: start, end: end)
//重载drawBezierPath方法
override func drawBezierPath()
//向控制台输出信息
print("Draw \(name!)")
// 建立一个 UIBezierPath 实例对象
let path = UIBezierPath()
//调用实例path的move方法移动
path.move(to:start!)
//调用实例path的addLine方法画线
path.addLine(to: end!)

class Rectangle:Shape
/左上角采用基类Shape中的属性origin
//宽度和高度,一般可以采用CGSize
var size : CGSize?
//构造器
init(name: String, origin: CGPoint,size : CGSize) 1
super.init (name: name, origin: origin)
self.size = size
convenience init(origin: CGPoint , size : CGSize) f
self.init (name: "Rectangle", origin: origin, size: size))
/ / 重载 drawBezierPath方法
override func drawBezierPath()i
/1向控制台输出信息
print("Draw \(name!) ")
//建立一个UIBezierpath实例对象
let path =UIBezierPath(rect: CGRect(origin: origin!, size: size!))//设置实例path 的线条宽度
path.lineWidth = lineWidth!
//设置实例path的线条颜色
lineColor?.setStroke()
//画出线条
path.stroke()
}
}
class Circle :Shape一
//圆心坐标
var center: CGPoint?
//半径长度
var raduis : CGFloat?
/1椭圆的宽度和高度,一般可以采用CGSize
var size : CGSize?
//构造器
init (name: String,oriqin: CGPoint, center: CGPoint, raduis : CGEloat, size :CGSize)
super.init (name: name, origin: origin)
self.center = center
self.raduis = raduis
self.size = size
一
convenience init(center : CGPoint,raduis : CGFloat) 一
let x = center.x - raduis
let y = center.y - raduis
self.init(name: "Circle",origin:CGPoint(x:x,y:y), center: center, raduis: raduis, size: CGSize(width: raduis, height; raduis))
convenience init(center : CGPoint, size : CGSize) 一
let x= center.x- size.width/2
let y = center.y - size.height/2
self.init(name: "Oval/Ellipse", origin: CGPoint(x:x,y:y), center:center,raduis:0, size:size)
// 重载 drawBezierPath方法
override func drawBezierPath()i
//向控制台输出信息
print("Draw
\(name!)")
// 建立一个UIBezierpath实例对象


class Polygons:Shape(
//多边形主要是通过多个顶点相互连接来绘图
//顶点数组
var points : Array<CGPoint>?
init(name: String, origin: CGPoint, points: Array<CGPoint>)
super.init (name: name, origin: origin)
self.points = points
convenience init(points : Array<CGPoint>) 一
if points.count ==3
self.init(name:"Triangel", origin: points.first!, points: points)
else if points.count >= 3(
self.init(name: "Polygons", origin: points,first!, points: points))
else (
let origin = CGPoint(x: 0, y: 0)
self.init (name: "Error", origin: origin, points: points)
// 重载drawBezierPath方法
override func drawBezierPath()
//向控制台输出信息
upraw(name!)")

classPolygons:Shape (
11多边形主要是通过多个顶点相互连接来绘图
//顶点数组
var points: Array<CGPoint>?
init(name: String, origin: CGPoint, points : Array<CGPoint>)
super.init (name: name, origin: origin)
self.points =points
convenience init(points : Array<CGPoint>)(
if points.count== 3 (
self.init(name: "rriangel", origin: points.first!, points: points)
]
else if points.count >= 3 
self.init(name: "Polygons", origin: points.first!, points: points))
else
let origin = CGPoint(x: 0, y: 0)
self.init(name: "Error", origin: origin, points: points)] 
]
// 重载 drawBezierPath方法
override func drawBezierPath()i
//向控制台输出信息
print("Draw \(name!)")
//如果不能识别,直接返回
if(name =="Error")
return
}
//建立一个UIBezierPath 实例对象
let path = UIBezierPath()
//调用实例path的move 方法移动
path.move(to:origin!)
for each in points!
//调用实例path的addLine 方法画线
path.addLine(to:each)
)
path.close()
//设置实例path 的线条宽度
path.lineWidth lineWidth!
//设置实例path 的线条颜色
lineColor?.setStroke()
//画出线条
path.stroke()
path.fill()
}
}

classFiveStar :Shape [
/1五角星和正五边形较为类似
//中心坐标
var center : CGPoint?
//半径
var radius :CGFloat?
/1旋转的角度
var angel: CGFloat?
//构造器
init (name: String, origin: cGpoint, center: cGpoint, radius: CGFloat,angel:CGFloat)
super.init(name: name, origin:origin)
self.center = center
self.radius = radius
self.angel = angel
一
convenience init(center : CGPoint, radius : CGFloat,angel:CGFloat
=0)
let x = center.x - radius
let y = center.y - radius
self.init (name: "FiveStar", origin: CGPoint(x:x,y:y), center: center, radius: radius,angel:angel)
//自定义方法drawBezierPath用于画五角星
overridefunc drawBezierPath()(
//调用贝塞尔曲线函数UIBezierpath()
let path = UIBezierPath()
/1五角星旋转顶点
let i= 360/angel!
let xzAngle = CGFloat.pi*2/i
let xzX=(center?.x)!- sin(xzAngle)★radius!
let xzY=(center?.y)!- cos(xzAngle)*radius!
let pl = CGPoint(x: xzX, y: xzY)
path.move(to: p1)
let angle = CGFloat.pi*4/5
for i in 1...5
let x=(center?.x)!- sin(CGFloat(i)*angle+xzAngle)*radius! let y=(center?.y)!- cos(CGFloat(i)★angle+xzAngle)★radius!path.addLine(to: CGPoint(x: x, y: y))
path.close()
//线条宽度
path.lineWidth = lineWidth!
// 线条颜色为 red 红色
lineColor?.setStroke()
//画出这个圆
path.stroke()
}
}

.4·4 项目实现
ViewController.swift
GeometryBand
Created by Zhifeng Chen on 2020/8/4.
Copyright  2020年 Zhifeng Chen. A1lrights reserved.
importUIKit
import Foundation
importAVFoundation
class Shape (
//名称
var name :String?
/1声音播放器
var soundPlayer :AVAudioPlayer?
//声音文件名称
var soundFile : String?
//UIBezierPath
var path: UIBezierPath?
//selected?
var selectedFlag:Bool false
//左上角的位置坐标
var origin : CGPoint?
//线条颜色
var lineColor:UIColor?= UIColor.red
//填充颜色
var fillColor: UIColor?= UIColor.green
// 线条宽度
var lineWidth: CGFloat?=5
//构造器函数init
init (name : String, origin : CGPoint,soundFile : String ="DO.m4a”self.name = name
self.origin = origin
self.soundFile = soundFile
一
//便利构造器函数init
convenience init(origin : CGPoint)
self.init(name: "Shape Bassclass", origin: origin)
//自定义方法drawBezierPath用于画图
func drawBezierPath()(
//向控制台输出信息
print("Draw \(name!)")
一
func playAudio()(
print("Play sound:\(soundFile!)")
let path = Bundle.main.path(forResource: soundFile, ofType: nil) let url = URL(fileURLWithPath: path!)
soundPlayer = try? AVAudioPlayer(contentsOf:url)
soundPlayer?.play()
一
func isSelected(point : CGPoint) -> Bool(
if (path?.contains(point))!(
selectedFlag = true
return trueelse一
selectedFlag = false
return false
}
}
}
//线段的起点
class Line : Shape
//线段的终点
var start : CGPoint?
var end : CGPoint?
//构造器
soundFile :String="FA.m4a")
super.init (name: name, origin: origin,soundFile:soundFile)
end =en at origin,som oint self.end =end
self.start = start
convenience init(start : CGPoint , end : CGPoint)
self.init (name: "Line", origin: start, start: start, end: end// 重载 drawBezierPath 方法
override func drawBezierPath()(
//向控制台输出信息
print("Draw \(name!)")
// 建立一个 UIBezierPath 实例对象
path = UIBezierPath()
//调用实例path的move 方法移动
path?.move(to:start!)
//调用实例path的addLine方法画线
path?.addLine(to: end!)
//设置实例path 的线条宽度
path?.lineWidth= lineWidth!
//设置实例patn的线条终端样式.round或者.square
path?.lineCapStyle =.round
//设置实例 path的线条颜色
lineColor?.setStroke()
//画出线条
path?.stroke()
class Rectangle: Shape
//左上角采用基类Shape中的属性origin
//宽度和高度,一般可以采用cGSize
var size : CGSize?
//圆角的大小
var corner : CGFloat?
//构造器
init (nane: String, origin: CGPoint, size: CGSize, corner: CGFloat,sounaFileString="LA.m4a") i
super.init(name: name, origin: origin,soundFile:soundFile) self.size = size
self.corner = corner
convenience init (origin: CGPoint, size : CGSize, corner: CGFloat =0)(self.init (name: "Rectangle", origin: origin, size: size, corner: correr
// 重载 drawBezierPath 方法画矩形或者正方形
override func drawBezierPath()(
//向控制台输出信息
pzint("Draw \(name!)")
// 建立一个 UIBezierPath 实例对象
path = UIBezierPath(roundedRect: CGRect (origin: origin!, size: size!), cornerRadius:corner!)
if selectedFlag f
let dashes: [CGFloat] =[1,3]
path?. setLineDash(dashes, count: dashes.count, phase: 0)
//设置实例path的线条宽度
path?.lineWidth = lineWidth!
//设置实例path的线条颜色
lineColor?.setStroke()
//画出线条
path?.stroke()
class Circle :Shape (
//圆心坐标
var center : CGPoint?
// 半径长度
var raduis :CGFloat?
//椭圆的宽度和高度,一般可以采用CGSize
var size :CGSize?
//构造器
init (name: String, origin: CGPoint, center :CGPoint, raduis : CGFloat, size: CGSize,soundFile : String ="MI.m4a") (
super.init (name: name, origin: origin,soundFile:soundFile) self.center = center
self.raduis = raduis
self.size = size
)
convenience init(center : CGPoint,raduis : CGFloat) [
let x = center.x - raduis
let y = center.y - raduis
self.init(name: "circle", origin: CGPoint(x:x,y:y), center: center, raduis: raduis, size: CGSize(width: raduis, height: raduis))
)
convenience init(center: CGpoint, size : CGsize)
let x= center.x- size.width/2
let y = center.y - size,height/2
self.init (name: "Oval/E1lipse", origin: CGPoint(x:x,y:y), center: center, raduis:0, size: size)
//重载drawBezierPath方法画圆或者椭圆
override func drawBezierPath()(
//向控制台输出信息
print("Draw \(name!)")
//建立一个UTBezierPath 实例对象
path = UIBezierPath(ovalIn: CGRect(origin: origin!, size: size!)) if selectedFlag [
let dashes: [CGFloat] =[1,3]
path?.setLineDash (dashes, count: dashes.count, phase: 0)
// 设置实例 path 的线条宽度
path?.lineWidth = lineWidth!
//设置实例path的线条颜色
lineColor?.setStroke()
//画出线条
path?.stroke()
class Polygons :Shape 
//多边形主要是通过多个顶点相互连接来绘图
//顶点数组
var points :Array<CGPoint>?
//构造器
init (name: String, origin: CGPoint, points: Array<CGPoint>,soundFile: String
"RE.m4a")super.init (name: name, origin: origin, soundFile: soundFile) self.points = points
)
convenience init(points:Array<CGpoint>)
if points.count == 3
self.init (name: "Triangel", origin: points.first!, points:
points)
)
else if points.count >= 3
self.init (name: "Polygons", origin: points.first!, points:
points)
}
eise
let oriqin CGPoint(x:0,y:0)
self.init (name: "Error", origin: origin, points: pointa
//重载drawBezierPath方法画多边形
override func drawBezierPath()
//向控制台输出信息
print("Dxaw\(name!)"
//如果不能识别,直接返回
if (name "Exrcr")
return
//建立一个 UTBezierPath 实例对象
path = UIBezierPath()
//调用实例path的move方法移动
path?.move(to:origin!)
for each in points!(
//调用实例path的addT,ine 方法画线
path?.addLine(to:each)
path?.close()
//设置实例path 的线条宽度
path?.lineWidth =lineWidth!
//设置实例path 的线条颜色
lineColor?.setStroke()
//画出线条
path?.stroke()
path?.fill()
class FiveStar : Shape f
//五角星和正五边形较为类似
//中心坐标
var center :CGPoint?
//半径
var radius : CGFloat?
//旋转的角度
var angel : CGFloat?
//1构造器
init (name: String, origin: CGPoint, center :CGPoint, radius:CGFloat,angel CGFloat,soundFile: String ="SO.m4a")
super.init(name: name, origin:origin,soundFile:soundFile) self.center = center
self.radius = radius
self.angel = angel
1
convenience init(center : CGpoint, radius: CGFloat,angel : CGFloat C)
let x = center.x - radius
let y = center.y -radius
self.init (name: "FiveStar", origin: CGPoint(x:x,y:y), center: center, radius: radius, angel: angel)
)
/1自定义方法drawBezierPath用于画五角星
override func drawBezierPath()(
//向控制台输出信息
print("Draw \(name!)")
// 调用贝塞尔曲线函数 UIBezierPath()
path = UIBezierPath()
//五角星旋转顶点
let i= 360/angel!
let xzAngle = CGFloat.pi*2/i
let xzX=(center?.x)!- sin(xzAngle)*radius!
let xzY=(center?.y)!- cos (xzAngle)*radius!
let pl = CGPoint(x: xzX, y:xzY)
path?.move(to:pl)
let angle = CGFloat.pi*4/5
for i in 1...5 (
let x=(center?.x)!- sin(CGFicat(i)*angle+xzAngle)*radius! let y=(center?.y)!- cos(CGFloat(i)*angle+xzAngle)*radius! path?.addLine(to: CGPoirt(x: x, y: y))
)
path?.close()
if selectedFlag i
let dashes:[CGFloat] = [1, 3]
path?,setIineDash(dashes, count: dashes.count, phase: 0))
//线条宽度
path?.lineWidth = lineWidth!
//线条颜色为red红色
lineColor?.setStroke()
//画出这个圆
path?.stroke()
1
CzfView: UIView
class
//成员变量(属性) shapes,其类型为Array<Shape>
private var shapes : Array<Shape>=[]
//重载UIView的draw方法
override func draw( rect:CGRect)
一
//调用 shapes这个数组中的每个实例的方法
for s in shapes{
    s.drawBezierPath()
//增加实例到数组 shapes 中
func add(shape : Shape)
shapes.append(shape)
)
// 触摸事件
override funetouchesBegan( touches:Set<UITouch>,withevent: UIEvent?)
// 获得UITouch 集合
let touch:UITouch = touches.fizst! as UITouch
// 获得触摸所在位置的坐标
let point = couch.location(in: self)
//调用shapes 这个数组中的每个实例的方法
for s in shapes
//如果被选中
if s.isSelected(point: point)
//声音播放
s.playAud_o()
//更新屏幕显示
self.setNeedsDisplay()
class ViewController: UIviewController f
override func viewDidLoad()[
super.viewDidLoad()
// Do any additional setup after lcading the view, typicallyfrom a nib.
//此处调用FiveStar类,建立一个对象(实例)star
//五角星的中心坐标为(180,180)
let starCenter = CGPoint(x: 180, y: 180)
/1五角星的半径设定了90,旋转角度为15let star = FiveStar(center: starCenter, radius: 50, angel: 45)star.lineColor = UIColor.blue
//此处调用Circle类,建立一个对象oval
let ovalCenter = CGPoint(x:100, y:300)
let ovalSize = CGSize(width: 100, height: 60)
let oval = Circle(center: ovalCenter, size: ovalSize)//此处调用Rectangle类,建立一个对象rect
let rectorigin = CGPoint(x: 60, y:50)
组娃
let rectsize = cGsize (width: 100, height: 50)
let rect = Rectangle (origin: rectorigin, size: rectSize, corner: 6)rect.lineColor=UIColor.gray
/1此处建立了一个CzfView的实例myView
let myView = CzfView(frame: CGRect(x: 0, y: 0,width: self.view. frame.size.width, height: self.view.frame.size.height))
//清除背景色
myView.backgroundColor= UIColor.clear
//赋值给myView中的成员变量(属性)shape
myView.add(shape:star)
myView.add(shape:oval)
myView.add(shape:rect)
//显示myView
self.view.addSubview(myView)
}
}