Я пишу элементы построения приложения, состоящие из CGPoints. У меня есть 2 кнопки: makeRectangle
и makeTriangle
. Для этапа построения/рисования я использую три метода для прямоугольника и три метода для треугольника внутри drawRect
.
Я застрял с моим кодом в drawRect
. В if-else-statement
каждый метод меняет схему построения/чертежа на предыдущий элемент при каждом нажатии кнопки.
Если я уже построил прямоугольник, а затем нажимаю кнопку makeTriangle
, я получаю новый треугольник, но мой прямоугольник превращается в треугольник с одной несоединенной точкой.
Есть ли обходной путь или мне не следует использовать метод drawRect
?
Вот сообщение SO по теме drawRect
: graphics-vs-su">РисоватьRect или не рисоватьRect
Объявление элемента:
enum Element {
case point1(point: CGPoint)
case point2(point: CGPoint)
case point3(point: CGPoint)
case point4(point: CGPoint)
func coord() -> [CGPoint] {
switch self {
case .point1(let point): return [point]
case .point2(let point): return [point]
case .point3(let point): return [point]
case .point4(let point): return [point]
}
}
func buildQuadPath(path: CGMutablePath) {
switch self {
case .point1(let point): CGPathMoveToPoint(path, nil, point.x, point.y)
case .point2(let point): CGPathAddLineToPoint(path, nil, point.x, point.y)
case .point3(let point): CGPathAddLineToPoint(path, nil, point.x, point.y)
case .point4(let point): CGPathAddLineToPoint(path, nil, point.x, point.y)
CGPathCloseSubpath(path)
}
}
func buildTriPath(path: CGMutablePath) {
switch self {
case .point1(let point): CGPathMoveToPoint(path, nil, point.x, point.y)
case .point2(let point): CGPathAddLineToPoint(path, nil, point.x, point.y)
case .point3(let point): CGPathAddLineToPoint(path, nil, point.x, point.y)
default:
CGPathCloseSubpath(path)
}
}
}
Способы построения и рисования треугольника и прямоугольника:
func buildTriPath() -> CGMutablePath {
let path = CGPathCreateMutable()
_ = array.map { $0.buildTriPath(path) }
return path
}
func drawTriPath() {
let path = buildTriPath()
GraphicsState {
CGContextAddPath(self.currentContext, path)
CGContextStrokePath(self.currentContext)
}
}
func drawTriFill() {
let fill = buildTriPath()
GraphicsState {
CGContextAddPath(self.currentContext, fill)
CGContextFillPath(self.currentContext)
}
}
///////////////////////////////////////////////////////
func buildQuadPath() -> CGMutablePath {
let path = CGPathCreateMutable()
_ = array.map { $0.buildQuadPath(path) }
return path
}
func drawQuadPath() {
let path = buildQuadPath()
GraphicsState {
CGContextAddPath(self.currentContext, path)
CGContextStrokePath(self.currentContext)
}
}
func drawQuadFill() {
let fill = buildQuadPath()
GraphicsState {
CGContextAddPath(self.currentContext, fill)
CGContextFillPath(self.currentContext)
}
}
Две переменные помогают определить, нажата ли кнопка:
var squareB: Int = 0
var triangleB: Int = 0
@IBAction func makeTriangle(sender: AnyObject?) {
....................
....................
triangleB += 1
squareB = 0
}
@IBAction func makeRectangle(sender: AnyObject?) {
....................
....................
triangleB = 0
squareB += 1
}
drawRect
метод:
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
drawBG()
GraphicsState { self.drawMyPoints() }
if squareB >= 1 && triangleB == 0 {
buildQuadPath()
drawQuadPath()
drawQuadFill()
needsDisplay = true
}
else if triangleB >= 1 && squareB == 0 {
buildTriPath()
drawTriPath()
drawTriFill()
needsDisplay = true
}
drawBorder()
}
...и, наконец, файл Context.swift
:
import Cocoa
import CoreGraphics
extension NSView {
var currentContext : CGContext? {
get {
let unsafeContextPointer = NSGraphicsContext.currentContext()?.graphicsPort
if let contextPointer = unsafeContextPointer {
let opaquePointer = COpaquePointer(contextPointer)
let context: CGContextRef = Unmanaged.fromOpaque(opaquePointer).takeUnretainedValue()
return context }
else { return nil }
}
}
func GraphicsState(drawStuff: () -> Void) {
CGContextSaveGState(currentContext)
drawStuff()
CGContextRestoreGState(currentContext)
}
}
//the end of code