编辑代码

//
// Viewcontroller.swift
//GraphDemo
//
// Created by Zhifeng Chen on 2020/8/4.
// Copyright 2020 Zhifeng Chen. All rights
//
import UIkit

class CoreGraphUIVie UIView{

override func touchesBegan(_touches:Set<UITouch>, with event
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>, wit
self.backgroundColor = UIColor.blue
print("Moved:\(touches)")
classViewController: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 side : Int?
//左上角的位置坐标
var origin : cgpoint?
//线条颜色
var linecolor : UIColor = UIColor.red
//填充颜色
var fillcolor:ntcolor = UIColor.green
//线条宽度
var lineWidth :CGFloat= 2
//构造器函数init
init(name : string,side : Int,origin : cgpoint) {
self.name = name
self.sides = sides
self.origin = origin 
}
//自定义方法sayBello
func sayHello(){
nrint("Shape (name!),sides\(sidesl), and originCord is (\origin!.x),\(origin!.y)")
}
}
5.2.2实例化Shape//
// ViewController.swift
// ShapeDemo
//
// Created by Zhifeng Chen on 2020/8/4.
// Copyright O 2020 Zhifeng Chen. All rights reserved
//

import UIKit

class Shape{
//名称
var name string?
// 边数
var sides : Int?
//左上角的位置坐标
var origin :CGPoint?
//线条颜色
var lineColor :UIColor =UIColor. red
//填充颜色
var fill Color :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 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) )
myShape. sayHello()
}
}

5.2.3 重载UIView中的Draw函数
/ /
//ViewController. swift
//DrawMusic
//

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

import UIKit

class Shape {
//名称
var name :String?
//边数
var sides :Int?
//左上角的位置坐标
var origin :CGPoint?
//线条颜色
var lineColor :UIColor =UIColor. red
//填充颜色
var f illColor: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)) ")
}
}
class CzfView:UIView{
//成员变量(属性) shape,其类型为Shape
var shape :Shape?
//重载UIView的draw方法
override func draw( rect:CGRect) {
//判断shape变量是否为空值nil
guard let s =shape else {
return
}
//不为空,则调用shape 这个实例的方法
s. sayHello()
}
}
class ViewController:UIViewController {

override func viewDidLoad(){
super. viewDidLoad()
//Do any additional setup after loading the view, typically from anib.
//此处调用Shape类,建立一个对象(实例)myShape
let myShape =Shape(name:"BaseShape", sides:0, origin:CGPoint(x: 0 ,y :0 ) )
//此处建立了一个CzfView的实例myView
let widt
2.线段类Line
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)}
//重载drawBezierPath方法
override func drawBezierPath(){
//向控制台输出信息
print("Draw \(name!)")
//建立一个UIBezierPath实例对象
let 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()
}
}
3.矩形类Rectangle
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!)")
//建立一个UIBezierPath实例对象
let path =UIBezierPath(rect:CGRect(origin:origin!, size:size!))
//设置实例path的线条宽度
path. lineWidth =lineWidth!
//设置实例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){
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)
}
//重载drawBezierPath方法
override func drawBezierPath(){
//向控制台输出信息
print ("Draw \( name!)")
//建立一个UIBezierPath实例对象
let path =UIBezierPath(roundedRect:CGRect(origin:origin!, size: size!),cornerRadius:corner!)

//设置实例path的线条宽度
path. lineWidth =lineWidth!
//设置实例path的线条颜色
lineColor?. setStroke()
//画出线条
path. s
4.圆形类Circle
class Circle :Shape {
//圆心坐标
var center :CGPoint?
//半径长度
var raduis :CGFloat?
//椭圆的宽度和高度,一般可以采用CGSize
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)
}
//重载drawBezierPath方法
override func drawBezierPath(){
//向控制台输出信息
print("Draw \(name!)")
//建立一个UIBezierPath实例对象
let path =UIBezierPath(ovalIn:CGRect(origin:origin!, size:size!))
//设置实例path的线条宽度
path. lineWidth =lineWidth!
//设置实例path的线条颜色
lineColor?. setStroke()
//画出线条
path. stroke()
}
}
5.多边形类Polygons
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(){
//向控制台输出信息
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()
}
}
5.3.2五角星的绘制
class Fivestar :Shape {
//中心坐标
var center :CGPoint?
     //半径
     var radius :CGFloat?
     //旋转的角度
     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用于画五角星
     override func drawBezierPath(){
         //调用贝塞尔曲线函数UIBezierPath()
         let 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 p1 =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(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()
}
}
5.4奏响乐队凯歌
//构造器
      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
}
5.4.4 项目实现
//
//ViewController. swift
//GeometryBand
//
// Created by Zhifeng Chen on 2020/8/4.
//Copyright 2020 年Zhifeng Chen. All rights reserved.
//

import UIKit
import Foundation
import AVFoundation

class Shape {
     //名称
     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 f illColor: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{
      selectedFlag =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?iOS?开发基础教程(Swift版)
//构造器
      init(name:String, origin:CGPoint, size :CGSize, corner :CGFloat,soundFile:?String ="LA.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, corner: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()
    }
}
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/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?. fill ()
}
}
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 ×× = ( center?. x)!- sin(xzAngle)*radius!
         let xzY =(center?,y)!-cos(xzAngle)*radius!
         let p1 =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(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()
     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. drawBezierPath()
}
}
     //增加实例到数组shapes中
     func add(shape :Shape){
     shapes. append(shape)
}
     //触摸事件
      override func 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()
}
}
}
}
       class ViewController:UIViewController{
         override func viewDidLoad(){
          super. viewDidLoad()
       //Do any additional setup after loading the view, typically from anib.
       //此处调用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)
     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
     //此处建立了一个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)
}
       }