【问题标题】:Drawing a grid on a UIView in Swift在 Swift 中的 UIView 上绘制网格
【发布时间】:2017-09-24 13:58:36
【问题描述】:

我对 Swift 很陌生。我试图在 Swift 的 UIView 上绘制网格(如图形页面)。代码正在运行,但我没有看到任何行。我看不出我做错了什么。

在 Storyboard 中,我在 ViewController 上添加了一个视图。

在代码中,我创建了一个 GridView.swift 并将其添加到上面的视图中。这是 GridView 类的代码。正在调用函数 draw 并且代码运行时没有任何错误。它只是在做我认为它会做的事情。

它甚至没有画一条线(我删除了 for 循环并尝试画一条线)。这似乎很基本,应该可以工作。

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

【问题讨论】:

    标签: ios swift uiview


    【解决方案1】:

    只需复制并粘贴以下代码即可。我没有检查你绘制正确网格的逻辑我刚刚解决了不绘制问题。如果它绘制了错误的网格,那么我现在将重新检查您的网格逻辑,它只是帮助您使用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()
        }
    }
    

    【讨论】:

    • 谢谢。我看到我必须关闭路径并实际调用 stroke() 才能绘制。所以我只是“准备”稍后要绘制的对象,而 stroke() 实际绘制它。
    • 你的意思是说你想在有的时候画出来?比如按钮点击、滑动手势或一些特殊事件之后?
    • 我想说为什么我需要在路径对象上调用 stroke() 和 close()。
    • Stroke 是您在视图上绘制的路径的颜色。而 close 方法用于关闭绘图,以便系统可以从头到尾开始绘图。关闭定义绘图结束。
    • 网格不可见。我在控制器中添加了一个UIView,将类更改为GridView 。但没有显示任何网格。如何在视图中添加网格?
    【解决方案2】:

    如果您想在视图初始化时创建绘制逻辑,但您实际上想稍后绘制线条,即当某些特殊事件发生时。 Bellow 类有两个方法 drawGridWithStoreColorremoveGrid 这将帮助您在需要时绘制网格并在需要时删除网格。

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

    【讨论】:

      【解决方案3】:

      这类似于 Instagram 的创建模式 文本对齐网格。在viewDidLoad()中添加以下两个函数...

      func addVerticalGrid(){
          
          let Path = UIBezierPath()
          Path.move(to: CGPoint(x: view.bounds.midX, y: 0))
          Path.addLine(to: CGPoint(x: view.bounds.midX, y: view.frame.height))
          Path.close()
          
          let shapeLayer1 = CAShapeLayer()
          shapeLayer1.path = Path.cgPath
          shapeLayer1.strokeColor = UIColor.red.cgColor
          view.layer.addSublayer(shapeLayer1)
      }
      
      func addHorizontalGrid(){
          
          let Path = UIBezierPath()
          Path.move(to: CGPoint(x: 0, y: view.bounds.midY))
          Path.addLine(to: CGPoint(x: view.frame.width, y: view.bounds.midY))
          Path.close()
          
          let shapeLayer2 = CAShapeLayer()
          shapeLayer2.path = Path.cgPath
          shapeLayer2.strokeColor = UIColor.red.cgColor
          view.layer.addSublayer(shapeLayer2)
      }
      

      【讨论】:

        猜你喜欢
        • 2012-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-29
        • 2018-05-31
        • 1970-01-01
        • 2012-01-02
        相关资源
        最近更新 更多