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

Posted

技术标签:

【中文标题】如何在swift中以最简单的方式画一条线【英文标题】:How to draw a line in the simplest way in swift 【发布时间】:2015-07-22 16:37:16 【问题描述】:

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

【问题讨论】:

你对此做了哪些研究?你不明白哪些部分? 我不知道把代码放在哪里。 对于 Swift 3,您可以查看this article。 对于 Swift 3,请查看here。 查看这篇文章。 ***.com/a/50346827/1890317 【参考方案1】:

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

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() 进行更新。

【讨论】:

我认为这是我正在寻找的那种,但它没有显示线路没有显示 它给了我一个错误,说“方法没有覆盖其超类中的任何方法”它在第一行是“覆盖有趣的 drawRect(rect: CGRect) ” 你使用的类有超类吗? 这是我如何启动类“class TicTacToeViewController: UIViewController ”但这是第二个 viewControler 不是我创建这个来控制第二个 viewControler 的默认值 很抱歉,您可能必须在情节提要中创建一个自定义 UIView 为其创建一个新文件,然后在该新文件中实现此代码【参考方案2】:

使用 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()
    

【讨论】:

【参考方案3】:

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

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

可以在 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() 的自定义类(即 ExampleDraw.swift 中的第一个类)关联起来 em> 像这样:

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

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

【讨论】:

【参考方案4】:

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)

【讨论】:

【参考方案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】:

我也在这个话题上苦苦挣扎。 在 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()

【讨论】:

【参考方案7】:

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

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

如果你想以正确的方式来研究如何在 SpriteKit 中在坐标之间绘制路径。

希望这对您有所帮助! 史蒂夫

【讨论】:

【参考方案8】:

一般来说,你必须在 Core Graphics 中绘制一条路径。你可以按照这个例子:

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

【讨论】:

这个例子我已经看过很多次了,但是我不知道该把代码放在哪里。 进入你的视图子类的func draw(_ rect: CGRect) 方法。【参考方案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】:
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()
     


【讨论】:

【参考方案11】:

Storyboard 中快速而肮脏的修复:

    创建 UILabel 删除文本 将背景颜色设置为您想要的颜色 将高度限制设置为所需的线宽

【讨论】:

虽然问题是关于为井字游戏画一条线,但这条线应该更像一个斜线\ 奇怪的是,你选择了 UILabel,而你只需要一个 UIVIew,它是 UIKit 中一个更基本的类。

以上是关于如何在swift中以最简单的方式画一条线的主要内容,如果未能解决你的问题,请参考以下文章

如何在HTML中画一条线

在 Swift 3.x 中使用 UIBezierPath 画一条线

Swift 从一个圆的中心到另一个圆的边缘画一条线

如何使用 fabric.js 在画布上画一条线

如何在Android上使用谷歌地图或mapquest动态突出显示道路的一侧(或在旁边画一条线)

如何在 Sprite-kit 中画一条线