Drawing a grid on a UIView in Swift

荒凉一梦 提交于 2021-02-19 00:51:24

问题


I am very new to Swift. Am trying to draw a grid (like a graph page) on a UIView in Swift. The code is running but I don't see any lines. I don't see what I did wrong.

In the Storyboard I added a View onto the ViewController.

In code I created a GridView.swift and added it to the View above. Here is the code for GridView class. The function draw is being called and the code running without any errors. Its just doing what I thought it would do.

Its not even drawing one line (I remove the for loop and just try to draw one line). This seems so basic that it should work.

import Foundation
import UIKit

class GridView: UIView 
{
    fileprivate var gridWidthMultiple: CGFloat
    {
        return 10
    }
    fileprivate var gridHeightMultiple : CGFloat
    {
        return 20
    }

    fileprivate var gridWidth: CGFloat
    {   
        return bounds.width/CGFloat(gridWidthMultiple)
    }

    fileprivate var gridHeight: CGFloat
    {
        return bounds.height/CGFloat(gridHeightMultiple)
    }

    fileprivate var gridCenter: CGPoint {
        return CGPoint(x: bounds.midX, y: bounds.midY)
    }

    fileprivate func drawGrid()
    {
        let path = UIBezierPath()
        path.lineWidth = 5.0

        for index in 1...Int(gridWidthMultiple) - 1
        {
            let start = CGPoint(x: CGFloat(index) * gridWidth, y: 0)
            let end = CGPoint(x: CGFloat(index) * gridWidth, y:bounds.height)
            path.move(to: start)
            path.addLine(to: end)
        }
    }

    override func draw(_ rect: CGRect)
    {
        drawGrid()
    }
}

回答1:


Just Copy and paste the below code and you will be good to go. I haven't check your logic of drawing correct grid i have just solved the not drawing issue. If it draw wrong grid then i will re-check your grid logic for now it just help you to draw something using UIBezierPath

class GridView: UIView
{
    private var path = UIBezierPath()
    fileprivate var gridWidthMultiple: CGFloat
    {
        return 10
    }
    fileprivate var gridHeightMultiple : CGFloat
    {
        return 20
    }

    fileprivate var gridWidth: CGFloat
    {
        return bounds.width/CGFloat(gridWidthMultiple)
    }

    fileprivate var gridHeight: CGFloat
    {
        return bounds.height/CGFloat(gridHeightMultiple)
    }

    fileprivate var gridCenter: CGPoint {
        return CGPoint(x: bounds.midX, y: bounds.midY)
    }

    fileprivate func drawGrid()
    {
        path = UIBezierPath()
        path.lineWidth = 5.0

        for index in 1...Int(gridWidthMultiple) - 1
        {
            let start = CGPoint(x: CGFloat(index) * gridWidth, y: 0)
            let end = CGPoint(x: CGFloat(index) * gridWidth, y:bounds.height)
            path.move(to: start)
            path.addLine(to: end)
        }

        for index in 1...Int(gridHeightMultiple) - 1 {
            let start = CGPoint(x: 0, y: CGFloat(index) * gridHeight)
            let end = CGPoint(x: bounds.width, y: CGFloat(index) * gridHeight)
            path.move(to: start)
            path.addLine(to: end)
        }

        //Close the path.
        path.close()

    }

    override func draw(_ rect: CGRect)
    {
        drawGrid()

        // Specify a border (stroke) color.
        UIColor.purple.setStroke()
        path.stroke()
    }
}



回答2:


if you want make the draw logic when view is initialise but you actually want to draw the lines later i.e. when some special event occur. Bellow class have two methods drawGridWithStoreColor and removeGrid this will help you to draw grid when ever you want and remove grid when ever you want.

class GridView: UIView
{
    private var path = UIBezierPath()
    var gridLayer: CAShapeLayer?

    fileprivate var gridWidthMultiple: CGFloat
    {
        return 10
    }
    fileprivate var gridHeightMultiple : CGFloat
    {
        return 20
    }

    fileprivate var gridWidth: CGFloat
    {
        return bounds.width/CGFloat(gridWidthMultiple)
    }

    fileprivate var gridHeight: CGFloat
    {
        return bounds.height/CGFloat(gridHeightMultiple)
    }

    fileprivate var gridCenter: CGPoint {
        return CGPoint(x: bounds.midX, y: bounds.midY)
    }

    fileprivate func drawGrid()
    {
        path = UIBezierPath()
        path.lineWidth = 5.0

        for index in 1...Int(gridWidthMultiple) - 1
        {
            let start = CGPoint(x: CGFloat(index) * gridWidth, y: 0)
            let end = CGPoint(x: CGFloat(index) * gridWidth, y:bounds.height)
            path.move(to: start)
            path.addLine(to: end)
        }


    }

    //Call this method with your stroke color when you want to draw this grid
    func drawGridWithColor(borderColor: UIColor) {
        //Close the path.
        path.close()
        if gridLayer == nil {
            gridLayer = CAShapeLayer()
            gridLayer?.lineWidth = 5.0;
            gridLayer?.path = path.cgPath
            gridLayer?.strokeColor = borderColor.cgColor

            self.layer.addSublayer(gridLayer!)
            //Above line will add this grid at the very top of this view.



            // if you want to add this grid below some layer/object you can use method
            //self.layer.insertSublayer(gridLayer, at: 0)
            //Give the index number to this method so that it can place this grid at the index

        }else {
            gridLayer?.strokeColor = borderColor.cgColor
        }
    }

    func removeGrid() {
        guard let gLayer = gridLayer else {return}
        gLayer.removeFromSuperlayer()
    }

    override func draw(_ rect: CGRect)
    {
        drawGrid()
    }
}


来源:https://stackoverflow.com/questions/46390838/drawing-a-grid-on-a-uiview-in-swift

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!