编辑代码

//
 ViewController.swift
GraphDemo
//
Created by Zhifeng Cheng Chen . All rights reserved.
//
import UIKit
class CoreGraphUIView : UIView {
    override func touchesBegan(_touches:Set<UITouch>, with event: UIEvent?){
        self.backgroundColor = UIColor.red
        print("Begin:\(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)

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(name : String, sides : Int, origin : CGPoint) {
        self.name = name
        self.sides = sides
        self.origin = origin
    }
    func sayHello(){
        print("Shape is \(name!),sides \(sides!), and originCord is(\(origin!.x),\(origin!.y))")
    }
}
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(name : String, sides : Int, origin : CGPoint) {
        self.name = name
        self.sides = sides
        self.origin = origin
    }
    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.
        let myShape = Shape(name:"BaseShape", sides: 0, origin: CGPoint(x: 0, y: 0))
        myShape.sayHello()
    }
}

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(name : String, sides : Int, origin : CGPoint) {
        self.name = name
        self.sides = sides
        self.origin = origin
    }
    func sayHello(){
        print("Shape is \(name!),sides \(sides!), and originCord is(\(origin!.x),\(origin!.y))")
    }
}
class CzfView : UIView {
    var shape : Shape?
    override func draw(_ rect: CGRect) {
        guard let s = shape else {
            return
        }
        s.sayHello()
    }
}
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from anib.
        let myShape = Shape(name:"BaseShape", sides: 0, origin: CGPoint(x:0, y: 0))
        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 = myShape
        self.view.addSubview(myView)
    }
}
func drawBezierPath () {
    let path = UIBezierPath()
    let center : CGPoint = CGPoint(x: 100, y: 100)
    let radius : CGFloat = 80
    path.addArc(withCenter: center, radius: radius, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true)
    path.lineWidth = 5
    UIColor.red.setStroke()
    path.stroke()
}
s.drawBezierPath()
myView.backgroundColor = UIColor.clear

class Shape {
    var name : String?
    var origin : CGPoint?
    var lineColor : UIColor? = UIColor.red
    var fillColor : UIColor? = UIColor.green
    var lineWidth : CGFloat? = 5
    init(name : String, origin : CGPoint) {
        self.name = name
        self.origin = origin
    }
    convenience init(origin : CGPoint) {
        self.init(name:"Shape Bassclass", origin: origin)
    }
    func drawBezierPath() {
        print("Draw \(name!)")
    }
}
class Line : 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)
    }
    override func drawBezierPath(){
        print("Draw \(name!)")
        let path = UIBezierPath()
        path.move(to: start!)
        path.addLine(to: end!)
        path.lineWidth = lineWidth!
        path.lineCapStyle = .round
        lineColor?.setStroke()
        path.stroke()
    }
}
class Rectangle : Shape {
    //左上角采用基类Shape 中的属性 origin
    //宽度和高度,一般可以采用 CGSize
    var size : CGSize?
    //构造器  
    init(name: String, origin: CGPoint , size : CGSize) {
        super.init(name: name, origin: origin)
        self.size = size
    }
    convenience init(origin: CGPoint , size : CGSize) {
        self.init(name: "Rectangle", origin: origin, size: size)
    }
    //重载drawBezierpath
    override func drawBezierPath(){
        print("Draw \(name!)")
        let path = UIBezierPath(rect: CGRect(origin: origin!, size: size!))
        path.lineWidth = lineWidth!
        lineColor?.setStroke()
        path.stroke()
    }
}

class Rectangle : Shape {
    var size : CGSize?
    var corner : CGFloat?
    init(name: String, origin: CGPoint , size : CGSize, corner : CGFloat) {
        super.init(name: name, origin: origin)
        self.size = size
        self.corner = corner
    }
    convenience init(origin: CGPoint , size : CGSize, corner : CGFloat = 0) {
        self.init(name: "Rectangle", origin: origin, size: size, corner : corner)
    }
    override func drawBezierPath() {
        print("Draw \(name!)")
        let path = UIBezierPath(roundedRect: CGRect(origin: origin!, size: size!), cornerRadius: corner!)
        path.lineWidth = lineWidth!
        lineColor?.setStroke()
        path.stroke()
    }
}

let myRect = Rectangle(origin: start, size: CGSize(width: 150, height: 100),corner: 8.0)
let myRect = Rectangle(origin: start, size: CGSize(width:150, height:100))

class Circle : Shape {
    var center : CGPoint?
    var raduis : CGFloat?
    var size : CGSize?
    init(name: String, origin: CGPoint, center : CGPoint, raduis : CGFloat, 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)
    }
    override func drawBezierPath(){
        print("Draw \(name!)")
        let path = UIBezierPath(ovalIn: CGRect(origin: origin!, size: size!))
        path.lineWidth = lineWidth!
        lineColor?.setStroke()
        path.stroke()
    }
}

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)
        }
    }
    override func drawBezierPath(){
        print("Draw \(name!)")
        if(name == "Error") {
            return
        }
        let path = UIBezierPath()
        path.move(to: origin!)
        for each in points! {
            path.addLine(to: each)
        }
        path.close()
        path.lineWidth = lineWidth!
        lineColor?.setStroke()
        path.stroke()
        path.fill()
    }
}

class FiveStar : Shape {
    var center : CGPint?
    var raduis : CGFloat?
    var angel : CGFloat?
    init(name: String, origin: CGPint, center : CGPint, raduis : CGFloat,angel : CGFloat ) {
        super.init(name: name, origin : origin)
        self.center = center
        self.raduis = raduis
        self.angel = angel
    }
    convenience init(center : CGPint, raduis : CGFloat,angel : CGFloat = 0) {
        let x = center.x - raduis
        let y = center.y - raduis
        self.init(name: "FiveStar", origin: CGPint(x:x,y:y), center: center, raduis: raduis, angel: angel)
    }
    override func drawBezierPath(){
        let path = UIBezierPath()
        let i = 360/angel!
        let xzAngle = CGFloat.pi*2/i
        let xzX = (center?.x)! - sin(xzAngle)*raduis!
        let xzY = (center?.y)! - cos(xzAngle)*raduis!
        let p1 = CGPoint(x: xzX, y: xzY)
        path.move(to: p1)
        let angle = CGFloat.pi*4/5l
        for i in 1...5 {
            let x = (center?.x)! - sin(CGFloat(i)*angle+xzAngle)*raduis!
            let y = (center?.y)! - cos(CGFloat(i)*angle+xzAngle)*raduis!
            path.addLine(to: CGPoint(x: x, y: y))
        }
        path.close()
        path.lineWidth = lineWidth!
        lineColor?.setStroke()
        path.stroke()
    }
}

init(name: String, origin: CGPint, center : CGPint,raduis : CGFloat,angel : CGFloat,soundFile : String = "SO.m4a") {
    super.init(name: name, origin: origin,soundFile: soundFile)
    self.center = center
    self.raduis = raduis
    self.angel = angel
}
}
viewController.swift
GeometryBand
Created by Zhifeng Chen on 2020/8/4.
Copyright @ 2020Zhifeng Chen. A1l rights reserved.
import UIKit
importFoundation
importAVFoundation
classShape
名称
/
var name :String?
//声音播放器
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 true
}
else {
    selectedFlaa = false
    return false
}
     }
}
class Line: Shape {
    //线段的起点
    var start :CGPoint?
    //线段的终点
    var end :CGPoint?
    //构造器
    init(name: String, origin: CGPoint, start :CGPoint, end :CGPoint,
 soundFile : String ="FA.m4a"){
             super.init (name: name, origin: origin,soundFile:soundFile) 
             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 实例对象
path = UIBezierPath()
//调用实例path的move 方法移动
path?.move(to: start!)
//调用实例path的addLine方法画线
path?.addLine(to: end!)
//设置实例path 的线条宽度
path?.lineWidth = lineWidth!
//设置实例path的线条终端样式.round或者.square
path?.lineCapStyle =.round
//设置实例path 的线条颜色
lineColor?.setStroke()
//画出线条
path?.stroke()
   }
}
class Rectangle: Shape {
//左上角采用基类Shape中的属性origin
//宽度和高度,一般可以采用CGSize
var size :CGSize?
//圆角的大小
var corner:CGFloat?
//构造器 
init (name: String, origin: CGPoint, size : CGSize,corner:CGFloat,soundFile:
String ="IA.m4a") {
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, comer : corner)
}    
//重载drawBezierPath 方法画矩形或者正方形
override func drawBezierPath()(
//向控制台输出信息
print("Draw \(name!)")
//建立一个UIBezierPath 实例对象
path = UIBezierPath(roundedRect: CGRect(origin: origin!, size: size!), cornerRadius: corner!)
if selectedFlag {
let dashes: [CGFloat] =[1,3]
path?,setLineDash(dashes, count: dashes.count, phase: 0)
}
// 设置实例path 的线条宽度
path?.lineWidth= lineWidth!
// 设置实例 path 的线条颜色
lineColor?.setStroke()
//画出线条
path?.stroke()
}
}
classCircle: 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/Ellipse",origin: CGPoint(x:x,y:y) center:
center,raduis:0,size:size)
}
// 重载 drawBezierPath方法画圆或者椭圆
override func drawBezierPath(){
//向控制台输出信息
print("Draw \(name!)")
//建立一个UIBezierPath 实例对象
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)
}
else {
let origin = CGPoint(x: 0, y: 0)
self.init(name: "Error", origin: origin, points:points)
}
}
//重载 drawBezierPath 方法画多边形
override func drawBezierPath(){
//向控制台输出信息
print("Draw \(name!)")
//如果不能识别,直接返回
if(name == "Error")
return
}
//建立一个UIBezierPath 实例对象
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?.fil1()
}
}
class Fivestar:Shape {
//五角星和正五边形较为类似
//中心坐标
var center : CGPoint?
//半径
var radius : CGFloat?
//旋转的角度
var angel: CGFloat?
//构造器
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
}
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 用于画五角星
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: 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!
trarate cadiig1e)rad1us!
path?.addLine(to: CGPoint(x: x, y: y))
}
path?.close()
if selectedFlag {
let dashes: [CGFloat]=[1, 3]
path?.setLineDash(dashes, count: dashes.count, phase: 0)
}
// 线条宽度
path?.lineWidth = lineWidth!
//线条颜色为 red 红色
lineColor?.setStroke()
//画出这个圆
path?.stroke()
}
}
class CzfView :UIView {
//成员变量(属性) shapes,其类型为Array<Shape>
private var shapes : Array<shape>=[]
//重载UIView的draw方法
override func draw( rect:CGRect) {
//调用shapes 这个数组中的每个实例的方法
for s in shapes {
s.drawBezlerPath()
}
}
//增加实例到数组 shapes 中
func add (shape:Shape) {
shapes.append(shape)
}
//触摸事件
overridefunc touchesBegan( touches: Set<UITouch>with event:
UIEvent?) {
//获得 UITouch 集合
let touch:UITouch touches.first! as UITouch
// 获得触摸所在位置的坐标
let point = touch.location(in: self)
//调用 shapes这个数组中的每个实例的方法
for s in shapes
//如果被选中
if s.isSelected(point:point) {
//声音播放
s.playAudio()
//更新屏幕显示
self.setNeedsDisplay()
}
}
}
}
classViewController:UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a
nib.
//此处调用FiveStar类,建立一个对象(实例)star
//五角星的中心坐标为(180,180)
let starCenter = CGPoint(x: 180, y: 180)
//五角星的半径设定了90,旋转角度为15度
let star = FiveStar(center: starCenter, radius: 50, angel: 45)
star.lineColor = UIColor.blue
//此处调用circle类,建立一个对象oval
let ovalcenter - CGPoint(x: 100, y:300)
letovalSize CGSize(width:100, height:60)
1et oval - circle(center: ovalCenter, size: ovalsize)
//此处调用Rectangle 类,建立一个对象 rect
let rectoriqin = CGPoint(x: 60, y:50)
let rectSize = CGSize(width: 100, height: 50)
letrect = Rectangle(origin: rectOrigin, size: rectSize, corner: 6)
rect.lineColor = UIColor.gray

//此处建立了一个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)
}
}