Как нарисовать линию простейшим способом в быстрой

Я новичок в Swift и XCode, и я пытаюсь сделать игру Tic Tac Toe. Я все выяснил, кроме как провести линию через три х или о. Я понятия не имею, как рисовать линии. Я искал ответ в Интернете и не могу понять его.

Ответы

Ответ 1

Попробуйте изучить UIBezierPath, это поможет вам много рисовать линии. Документация Вот пример:

override func drawRect(rect: CGRect) {
      var aPath = UIBezierPath()

      aPath.moveToPoint(CGPoint(x:/*Put starting Location*/, y:/*Put starting Location*/))

      aPath.addLineToPoint(CGPoint(x:/*Put Next Location*/, y:/*Put Next Location*/))

      //Keep using the method addLineToPoint until you get to the one where about to close the path

      aPath.closePath()

      //If you want to stroke it with a red color
      UIColor.redColor().set()
      aPath.stroke()
      //If you want to fill it as well 
      aPath.fill()
}

Убедитесь, что этот код введен в drawRect. Как в приведенном выше примере.

Если вам нужно обновить чертеж, просто позвоните setNeedsDisplay() для обновления.

Ответ 2

Обновление для Swift 3.x с использованием примера Epic Defeater

override func draw(_ rect: CGRect) {
        let aPath = UIBezierPath()

        aPath.move(to: CGPoint(x:20, y:50))

        aPath.addLine(to: CGPoint(x:300, y:50))

        //Keep using the method addLineToPoint until you get to the one where about to close the path

        aPath.close()

        //If you want to stroke it with a red color
        UIColor.red.set()
        aPath.stroke()
        //If you want to fill it as well
        aPath.fill()
    }

Ответ 3

Swift 3.1, внутри UIView:

public override func draw(_ rect: CGRect) {
    let context = UIGraphicsGetCurrentContext()
    context!.setLineWidth(2.0)
    context!.setStrokeColor(UIColor.red.cgColor)
    context?.move(to: CGPoint(x: 0, y: self.frame.size.height))
    context?.addLine(to: CGPoint(x: self.frame.size.width, y: 0))
    context!.strokePath()
}

Если вы хотите добавить строку в UIViewController, просто добавьте UIView с этой функцией в качестве подчиненного объекта UIViewController, ei:

let line = LineView(CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
self.view.addSubview(line)

Ответ 4

На самом деле спрашивающий не спрашивает, какой код использовать, он спрашивает, куда поместить код. На самом деле это хороший вопрос, потому что если вы поместите какой-либо графический код в "неправильное" место, ничего не будет нарисовано. "Неправильное" место для размещения кода находится в классе, который не является подклассом UIView. Если вы попытаетесь это сделать, код скомпилируется, но когда он запустится, вызов для получения графического контекста не будет выполнен, и вызовы следующих графических функций, таких как context?.Move(), не будут выполняться, поскольку контекст равен нулю.

В качестве примера, давайте создадим раскадровку с видом, кнопкой и меткой, перетащив соответствующие объекты из библиотеки объектов на раскадровку. Мой пример выглядит следующим образом, где белый квадрат - это представление (на самом деле это вспомогательное представление, поскольку основной экран также является представлением):

enter image description here

Можно рисовать графику на элементах управления Button и Label (и других типах элементов управления пользовательского интерфейса), поскольку UIButton и UILabel являются подклассами UIView.

Я также создал новый файл в проекте типа Swift и назвал его ExampleDraw.swift и поместил в него следующий код. Код содержит три класса для написания графики на виде, кнопке и метке. каждый класс переопределяет функцию draw() в базовом классе UIView:

import UIKit

class DrawOnView: UIView {
    override func draw(_ rect: CGRect) {
        let context = UIGraphicsGetCurrentContext()
        context?.setLineWidth(2.0)
        context?.setStrokeColor(UIColor.blue.cgColor)
        context?.move(to: CGPoint(x:0, y: 0))
        context?.addLine(to: CGPoint(x: 20, y: 30))
        context?.strokePath()

        print("in DrawOnView")
    }
}

class DrawOnButton: UIButton {
    override func draw(_ rect: CGRect) {
        let context = UIGraphicsGetCurrentContext()
        context?.setLineWidth(4.0)
        context?.setStrokeColor(UIColor.green.cgColor)
        context?.move (to: CGPoint(x: 0, y: 0))
        context?.addLine (to: CGPoint(x: 40, y: 45))
        context?.strokePath()

        print("in DrawOnButton")
    }
}

class DrawOnLabel: UILabel {
    override func draw(_ rect: CGRect) {
        let context = UIGraphicsGetCurrentContext()
        context?.setLineWidth(1.0)
        context?.setStrokeColor(UIColor.red.cgColor)
        context?.move (to: CGPoint(x: 0, y: 0))
        context?.addLine (to: CGPoint(x: 35, y: 45))
        context?.strokePath()

        print("in DrawOnLabel")
    }
}

Затем в главной раскадровке выберите вид, например:

enter image description here

Затем откройте Identity Inspector и свяжите это представление с пользовательским классом (т.е. первым классом в ExampleDraw.swift) с именем DrawOnView() следующим образом:

enter image description here

Сделайте то же самое для кнопки и метки, как показано ниже:

enter image description here

enter image description here

Затем запустите проект в симуляторе, и, надеюсь, графика отобразит вид, кнопку и метку следующим образом:

enter image description here

Ответ 5

Простая реализация SWIFT 4.1:

public override func draw(_ rect: CGRect) {
    guard let context = UIGraphicsGetCurrentContext() else { return }
    let lineWidth: CGFloat = 1.0
    context.setLineWidth(lineWidth)
    context.setStrokeColor(UIColor(style: .tertiaryBackground).cgColor)
    let startingPoint = CGPoint(x: 0, y: rect.size.height - lineWidth)
    let endingPoint = CGPoint(x: rect.size.width, y: rect.size.height - lineWidth)
    context.move(to: startingPoint )
    context.addLine(to: endingPoint )
    context.strokePath()
}

Очевидно, вам нужно настроить начальную и конечную точку.

Ответ 6

Используете ли вы SpriteKit? Если нет, вам действительно нужно делать для любых игр iOS, так как это облегчает манипулирование и добавление спрайтов (изображений) и других объектов игрового стиля.

Несмотря на то, что это не лучший способ с точки зрения передовых методов кодирования, очень простым способом добиться этого было бы создание нового представления, когда кто-то победит, проверьте, в каком направлении (из возможных 8) находится строка и затем соответствующим образом установите изображение этого вида. Изображения будут полупрозрачными (например, PNG) квадратами, каждая из которых содержит другую возможную линию.

Если вы хотите сделать это правильно, исследуйте, как рисовать пути в SpriteKit между координатами.

Надеюсь, это поможет! Стив

Ответ 7

Я тоже боролся за эту тему. В XCode 7.3.1, с версией Swift 2.2, самый простой способ нарисовать линию - создать игровую площадку и вставить в нее этот код. Надеюсь, что это помогает другим людям с этой простой задачей.

import UIKit
import XCPlayground

public class SimpleLine: UIView  {

    public init() {
        super.init(frame: CGRect(x: 0, y: 0, width: 480, height: 320))
        backgroundColor = UIColor.whiteColor()
    }

    public required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    public override func drawRect(rect: CGRect) {
        let context = UIGraphicsGetCurrentContext()
        CGContextSetLineWidth(context, 4.0)
        CGContextSetStrokeColorWithColor(context, UIColor.darkGrayColor().CGColor)
        CGContextMoveToPoint(context, 100, 100)
        CGContextAddLineToPoint(context, 300, 300)
        CGContextStrokePath(context)
    }

}

let firstLine = SimpleLine()

XCPlaygroundPage.currentPage.liveView = firstLine

Редактировать: обновление для Xcode 10.1 с версией Swift 4.2.1

import UIKit
import PlaygroundSupport

public class SimpleLine: UIView  {

    public init() {
        super.init(frame: CGRect(x: 0, y: 0, width: 320, height: 480))
        backgroundColor = .white
    }

    public required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    public override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }
        context.setLineWidth(4.0)
        context.setStrokeColor(UIColor.darkGray.cgColor)
        context.move(to: CGPoint(x: 40, y: 40))
        context.addLine(to: CGPoint(x: 280, y: 300))
        context.strokePath()
    }
}

PlaygroundPage.current.liveView = SimpleLine()

Ответ 8

В общем, вам нужно нарисовать путь в Core Graphics. Вы можете следовать этому примеру:

let context = UIGraphicsGetCurrentContext()
CGContextSetLineWidth(context, 2.0)
CGContextSetStrokeColorWithColor(context, color)
CGContextMoveToPoint(context, startPoint)
CGContextAddLineToPoint(context, endPoint)
CGContextStrokePath(context)

Ответ 9

Рисование в Swift 4.1

override func viewDidLoad() {
    super.viewDidLoad()
     self.lastPoint = CGPoint.zero
     self.red = 0.0
     self.green = 0.0
     self.blue = 0.0

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


//MARK: Touch events
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    isSwiping    = false
    if let touch = touches.first{
        lastPoint = touch.location(in: mainImageView)
    }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    isSwiping = true;
    if let touch = touches.first{
        let currentPoint = touch.location(in: mainImageView)
        UIGraphicsBeginImageContext(self.tempImageView.frame.size)
        self.tempImageView.image?.draw(in: CGRect(x:0, y:0,width:self.tempImageView.frame.size.width, height:self.tempImageView.frame.size.height))

        UIGraphicsGetCurrentContext()?.move(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
        UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: currentPoint.x, y: currentPoint.y))

        UIGraphicsGetCurrentContext()?.setLineCap(CGLineCap.round)
        UIGraphicsGetCurrentContext()?.setLineWidth(9.0)
        UIGraphicsGetCurrentContext()?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0)
        UIGraphicsGetCurrentContext()?.strokePath()


        self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        lastPoint = currentPoint
    }
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if(!isSwiping) {
        // This is a single touch, draw a point
        UIGraphicsBeginImageContext(self.tempImageView.frame.size)
        self.tempImageView.image?.draw(in: CGRect(x:0, y:0,width:self.tempImageView.frame.size.width, height:self.tempImageView.frame.size.height))
        UIGraphicsGetCurrentContext()?.setLineCap(CGLineCap.round)
        UIGraphicsGetCurrentContext()?.setLineWidth(9.0)

        UIGraphicsGetCurrentContext()?.move(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
        UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
        UIGraphicsGetCurrentContext()?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0)
        UIGraphicsGetCurrentContext()?.strokePath()
        self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
    }
}

Ответ 10

Ответ Epic Defeater обновлен до Swift 4.1

   func drawRect(rect: CGRect) {
        var aPath = UIBezierPath()

        aPath.move(to: CGPoint(x:/*Put starting Location*/, y:/*Put starting Location*/))

        aPath.addLine(to: CGPoint(x:/*Put Next Location*/, y:/*Put Next Location*/))

        //Keep using the method addLineToPoint until you get to the one where about to close the path

        aPath.close()

        //If you want to stroke it with a red color
        UIColor.red
        aPath.stroke()
        //If you want to fill it as well
        aPath.fill()
    }

Ответ 11

import UIKit

@IBDesignable class DrawView: UIView {

    override func draw(_ rect: CGRect) {
        let context = UIGraphicsGetCurrentContext()
        context?.setLineWidth(2.0)
        context?.setStrokeColor(UIColor.red.cgColor)
        context?.move(to: CGPoint(x: 210, y: 30))
        context?.addLine(to: CGPoint(x: 300, y: 200))
        context?.addLine(to: CGPoint(x: 100, y: 200))
        context?.addLine(to: CGPoint(x: 210, y: 30))
        context?.strokePath()
    } 

}