簡體   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