【问题标题】:Is there away setting UI Graphic Context drawing attribute once, instead of on draw everytime?是否有一次设置 UI 图形上下文绘图属性,而不是每次都绘制?
【发布时间】:2021-02-09 15:28:09
【问题描述】:

我有一个 Canvas UIView,如下所示。 (关注https://youtu.be/E2NTCmEsdSE

class Canvas: UIView {
    
    override func draw(_ rect: CGRect){
        super.draw(rect)
        
        guard let context = UIGraphicsGetCurrentContext() else { return }
        
        // Other codes
        
        context.setLineWidth(10)
        context.setLineCap(.round)
        context.strokePath()
    }
    
    // Other codes
}

看起来我只能在 draw 函数中使用 setLineWidthsetLineCap。这意味着无论何时发生平局,他们都会一次又一次地被设置。

我想知道,有没有办法让我在每次启动时设置一次绘图属性而不是一遍又一遍地设置?

【问题讨论】:

    标签: ios swift uiview uigraphicscontext


    【解决方案1】:

    AFAIK UIKit 使用上下文来绘制几乎所有内容,全局更改属性会产生巨大影响。

    您可以做的是扩展CGContext 以设置您想要的属性或使用您想要的属性执行笔划。

    extension CGContext {
      func applyAppStyle() {
        context.setLineWidth(10)
        context.setLineCap(.round)
      }
    
      func strokeWithAppStyle() {
        context.setLineWidth(10)
        context.setLineCap(.round)
        context.strokePath()
      }
    }
    

    【讨论】:

    • 谢谢@EmilioPelaez。转移到另一个功能很好。但事实是它仍然在draw 中被调用,因此被一遍又一遍地触发。我在想不要一遍又一遍地设置它。不确定这是否可能,或者上下文属性只需要一直设置?
    【解决方案2】:

    正如您所知道的,如果您不喜欢在 draw 方法中让它们沿着页面向下移动,您当然可以将多行代码移至实用函数。

    另一种可能性是预先在代码中构造一个 UIImage(通过绘制到 its 上下文中),然后将 that 绘制到draw 方法。然而,令人惊讶的是,这不如高效,因为这意味着存储所有像素,然后在绘制时将它们全部复制到上下文中。

    要理解的重要一点是,您的代码是正确的。你所做的就是你所做的。您的代码不是低效或缓慢的;它可能看起来冗长,但事情就是这样。绘图命令高度优化;毕竟,绘图是应用展示的精髓。

    请记住,上下文不一定会持续存在,并且对draw 的调用并不是特别频繁(事实上,在应用程序的生命周期中,视图被告知只绘制一次的情况并不少见)。

    所以只要遵守规则:当你被告知要画的时候,就画完整的画。

    【讨论】:

    • 谢谢,@Matt。我只是好奇,就像在 Android 中一样,我们可以设置 Paint() 值来设置线宽等是在 onDraw 函数之外完成的,因此无论调用多少次 onDraw ,它都只设置一次。但是在iOS中,看起来我们需要在draw期间设置context.setLineWidth(10),这似乎一遍又一遍地做同样的事情......所以我在这方面很困惑。
    • 我坚持我的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    相关资源
    最近更新 更多