繁体   English   中英

如何在swift中以最简单的方式画一条线

[英]How to draw a line in the simplest way in swift

我对 swift 和 Xcode 还很陌生,我正在尝试制作井字游戏。 除了如何通过三个 x 或 o 画一条线外,我已经弄清楚了一切。 我不知道如何画线。 我已经在网上寻找答案,但无法弄清楚。

尝试查看 UIBezierPath,它对绘制线条有很大帮助。 这是文档 这是一个例子:

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

    aPath.move(to: CGPoint(x:<#start x#>, y:<#start y#>))
    aPath.addLine(to: CGPoint(x: <#end x#>, y: <#end y#>))

    // Keep using the method addLine 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.lineWidth = <#line width#>
    aPath.stroke()
}

确保将此代码放在drawRect中,就像上面的示例一样。

如果您需要更新绘图,只需调用setNeedsDisplay()即可更新。

使用 Epic Defeater 的示例更新Swift 3.x

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()
    }

提问者并不是真的在问要使用什么代码,他是在问将代码放在哪里。 这实际上是一个好问题,因为如果您将任何图形代码放在“错误”的位置,则根本不会绘制任何内容。 放置代码的“错误”位置是在一个不是UIView子类的类中。 如果您尝试这样做,代码将编译,但在运行时,获取图形上下文的调用将失败,并且对以下图形函数的调用(例如context?.move() )将不会运行,因为上下文为nil .

例如,让我们通过将对象库中的相应对象拖到故事板上来创建一个带有视图、按钮和标签的故事板。 我的示例如下所示,其中白色方块是视图(实际上是子视图,因为主屏幕也是视图):

在此处输入图像描述

可以在 Button 和 Label 控件(以及其他类型的 UI 控件)上绘制图形,因为UIButtonUILabelUIView的子类。

我还在项目中创建了一个 Swift 类型的新文件,并将其命名为ExampleDraw.swift并将以下代码放入其中。 该代码包含三个类,用于在视图、按钮和标签上编写图形。 每个类都覆盖UIView基类中的draw()函数:

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")
    }
}

然后在主故事板中,选择视图,如下所示:

在此处输入图像描述

然后打开Identity Inspector并将该视图与名为DrawOnView()的自定义类(即 E xampleDraw.swift中的第一个类)相关联,如下所示:

在此处输入图像描述

对 Button 和 Label 执行相同的操作,如下所示:

在此处输入图像描述

在此处输入图像描述

然后在模拟器中运行项目,希望图形会像这样写在视图、按钮和标签上:

在此处输入图像描述

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,即:

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

我也在这个话题上苦苦挣扎。 在 XCode 7.3.1 和 Swift 2.2 中,画线的最简单方法是创建一个 Playground 并将此代码插入其中。 希望这可以帮助其他人记住这个简单的任务。

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

编辑:使用 Swift 版本 4.2.1 更新 Xcode 10.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()

简单的 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()
}

显然,您需要调整起点和终点。

你在使用 SpriteKit 吗? 如果没有,你真的应该为任何类型的 iOS 游戏做,因为它使操作和添加精灵(图像)和其他游戏风格的对象变得非常容易。

虽然在编码最佳实践方面根本不是最好的方法,但一个非常简单的方法是在有人获胜时创建一个新视图,检查该行的方向(可能的 8 个),然后设置此视图的图像相应。 图像将是半透明(例如PNG)正方形,每个正方形包含不同的可能线。

如果您想以正确的方式进行研究,请研究如何在 SpriteKit 中在坐标之间绘制路径。

希望这个对你有帮助! 史蒂夫

通常,您必须在 Core Graphics 中绘制路径。 您可以按照以下示例进行操作:

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

在 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()
    }
}

故事板中快速而肮脏的修复:

在此处输入图像描述

  1. 创建一个 UIView
  2. 将背景颜色设置为您想要的颜色
  3. 将高度约束设置为您想要的线宽
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()
    } 

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM