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()
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 (name : String, sides : Int, origin : CGPoint)f
self.name = name
self.sides = sides
self.origin = origin
func sayHello()t
print("Shape is \(name!),sides \(sides!), and originCord is(\(oriqin!.x),\(origin!.y))")
}
}
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 (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()
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(name : String, sides : Int, origin: CGPoint)
self.name = name
self.sides = sides
self.origin = origin
func sayHello()(
print("Shape:\(name!),sides\(sides!), origin (\(origin!.x),
(origin!.y)) ")
CzfView: UIView
[
class
var shape : Shape?
override func drawi rect: CGRect)(
guard let = shape else(
xeturn
1
s.sayHello()
classViewController:UIViewController
override func viewDidLoad() t
super.viewDidLoad()
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
/ / 显示 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)
override func drawBezierPath()
print("Draw \(name!)")
let path = UIBezierPath()
path.move(to:start!)
path.addLine(to: end!)
class Rectangle:Shape
/左上角采用基类Shape中的属性origin
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!) ")
let path =UIBezierPath(rect: CGRect(origin: origin!, size: size!))
path.lineWidth = lineWidth!
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)
override func drawBezierPath()i
print("Draw
\(name!)")
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()
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
一
convenience init(origin : CGPoint)
self.init(name: "Shape Bassclass", origin: origin)
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一
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
override func drawBezierPath()(
print("Draw \(name!)")
path = UIBezierPath()
path?.move(to:start!)
path?.addLine(to: end!)
path?.lineWidth= lineWidth!
path?.lineCapStyle =.round
lineColor?.setStroke()
path?.stroke()
class Rectangle: Shape
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
override func drawBezierPath()(
pzint("Draw \(name!)")
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?.lineWidth = lineWidth!
lineColor?.setStroke()
path?.stroke()
class Circle :Shape (
var center : CGPoint?
var raduis :CGFloat?
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)
override func drawBezierPath()(
//向控制台输出信息
print("Draw \(name!)")
path = UIBezierPath(ovalIn: CGRect(origin: origin!, size: size!)) if selectedFlag [
let dashes: [CGFloat] =[1,3]
path?.setLineDash (dashes, count: dashes.count, phase: 0)
path?.lineWidth = lineWidth!
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
override func drawBezierPath()
print("Dxaw\(name!)"
if (name "Exrcr")
return
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 f
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
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!)")
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!
lineColor?.setStroke()
path?.stroke()
1
CzfView: UIView
class
private var shapes : Array<Shape>=[]
override func draw( rect:CGRect)
一
for s in shapes{
s.drawBezierPath()
func add(shape : Shape)
shapes.append(shape)
)
override funetouchesBegan( touches:Set<UITouch>,withevent: UIEvent?)
let touch:UITouch = touches.fizst! as UITouch
let point = couch.location(in: self)
for s in shapes
if s.isSelected(point: point)
s.playAud_o()
self.setNeedsDisplay()
class ViewController: UIviewController f
override func viewDidLoad()[
super.viewDidLoad()
let starCenter = CGPoint(x: 180, y: 180)
/1五角星的半径设定了90,旋转角度为15度
let star = FiveStar(center: starCenter, radius: 50, angel: 45)star.lineColor = UIColor.blue
let ovalCenter = CGPoint(x:100, y:300)
let ovalSize = CGSize(width: 100, height: 60)
let oval = Circle(center: ovalCenter, size: ovalSize)
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.add(shape:star)
myView.add(shape:oval)
myView.add(shape:rect)
self.view.addSubview(myView)
}
}