【问题标题】:How to procedurally draw rectangle / lines in swift using CGContext如何使用 CGContext 在程序中快速绘制矩形/线条
【发布时间】:2014-08-10 15:09:59
【问题描述】:

我已经在互联网上搜索了几天,试图找到关于如何在 Swift 中以程序方式绘制矩形或线条的最简单的代码示例。我已经看到了如何通过覆盖 DrawRect 命令来做到这一点。我相信您可以创建一个 CGContext 然后绘制到图像中,但我很乐意看到一些简单的代码示例。或者这是一种可怕的方法?谢谢。

class MenuController: UIViewController 
{

    override func viewDidLoad() 
    {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = UIColor.blackColor()

        var logoFrame = CGRectMake(0,0,118,40)
        var imageView = UIImageView(frame: logoFrame)
        imageView.image = UIImage(named:"Logo")
        self.view.addSubview(imageView)

        //need to draw a rectangle here
    }
}

【问题讨论】:

    标签: swift cgcontext rect


    【解决方案1】:

    这是一个创建自定义 UIImage 的示例,该 UIImage 包含透明背景和一个红色矩形,其中的线条对角线穿过它。

    class ViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad();
    
            let imageSize = CGSize(width: 200, height: 200)
            let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: 100, y: 100), size: imageSize))
            self.view.addSubview(imageView)
            let image = drawCustomImage(size: imageSize)
            imageView.image = image
        }
    }
    
    func drawCustomImage(size: CGSize) -> UIImage {
        // Setup our context
        let bounds = CGRect(origin: .zero, size: size)
        let opaque = false
        let scale: CGFloat = 0
        UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
        let context = UIGraphicsGetCurrentContext()!
    
        // Setup complete, do drawing here
        context.setStrokeColor(UIColor.red.cgColor)
        context.setLineWidth(2)
    
        context.stroke(bounds)
    
        context.beginPath()
        context.move(to: CGPoint(x: bounds.minX, y: bounds.minY))
        context.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
        context.move(to: CGPoint(x: bounds.maxX, y: bounds.minY))
        context.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
        context.strokePath()
    
        // Drawing complete, retrieve the finished image and cleanup
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
    

    【讨论】:

    • 太棒了,这正是我想要的,也是一个非常有说服力的例子。感谢您的帮助。这是一种有效的绘图方式,还是有更好的方法?
    • 我认为这与使用 Quartz 进行此类绘图的效率差不多。通过将 CGRectGetMinX(bounds) 分配给一个变量并重复使用该变量,您可以在上述代码中获得一些迂腐但可能微不足道的效率——同样,这可能不会导致明显的速度提升。您可以使用 OpenGL 更快地绘制矢量,但它们没有那么灵活或好看。
    • 请注意,如果您想在此上下文中覆盖另一个 UIImage,如果您使用 CGContextDrawImage,它将被翻转。您必须改用image.drawInRect(bounds)
    【解决方案2】:

    使用 Swift 3.0 的更新答案

    class ViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad();
    
            let imageSize = CGSize(width: 200, height: 200)
            let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: 100, y: 100), size: imageSize))
            self.view.addSubview(imageView)
            let image = drawCustomImage(size: imageSize)
            imageView.image = image
        }
    }
    
    func drawCustomImage(size: CGSize) -> UIImage? {
        // Setup our context
        let bounds = CGRect(origin: CGPoint.zero, size: size)
        let opaque = false
        let scale: CGFloat = 0
        UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
    
        // Setup complete, do drawing here
        context.setStrokeColor(UIColor.red.cgColor)
        context.setLineWidth(5.0)
    
        // Would draw a border around the rectangle
        // context.stroke(bounds)
    
        context.beginPath()
        context.move(to: CGPoint(x: bounds.maxX, y: bounds.minY))
        context.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
        context.strokePath()
    
        // Drawing complete, retrieve the finished image and cleanup
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    
    let imageSize = CGSize(width: 200, height: 200)
    let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: 100, y: 100), size: imageSize))
    let image = drawCustomImage(size: imageSize)
    imageView.image = image
    

    【讨论】:

    • 我得到了各种各样的错误:“'CGContext' 类型的值没有成员'setStrokeColor',等等每个方法。似乎该方法记录在 Apple 的 API 参考中,但我是无法使它们与 Swift 3 一起使用..
    • 感谢您提供此信息。比以前更好,但似乎仍然是面向对象编程和其他方面的丑陋组合。哦,好吧,也许他们会在下一次迭代中(再次)修复它。
    【解决方案3】:

    当一名玩家获胜时,我使用公认的答案在井字游戏中画线。谢谢,很高兴知道它有效。不幸的是,我在让它同时在不同尺寸的 iPhone 和 iPad 上工作时遇到了一些问题。这可能是应该解决的问题。基本上我要说的是,根据您的情况,实际上可能不值得为所有代码带来麻烦。

    我的替代解决方案是在 Photoshop 中简单地制作定制的、更好看的线条,然后使用 UIImageView 加载它。对我来说,这要简​​单得多,运行得更好,看起来也更好。显然这真的取决于你需要它。

    步骤:

    1:下载或创建图片(最好保存为.PNG)

    2:将其拖入您的项目中

    3:将 UIImage 视图拖到故事板中

    4:点击图像视图,在属性检查器中选择图像

    5:按住 Ctrl 键单击 Image View 并将其拖到您的 .swift 文件中以声明一个 Outlet

    6:设置自动布局约束,使其在所有设备上都能轻松运行

    在屏幕上和屏幕外动画、旋转和转换图像视图也可以说更容易

    要更改图像:

    yourImageViewOutletName.image = UIImage(named: "ImageNameHere")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-08
      • 1970-01-01
      • 2023-04-05
      • 2022-01-07
      相关资源
      最近更新 更多