如何使用 swift 清除和重绘 UIView 的内容(存在于视图控制器中)?

Posted

技术标签:

【中文标题】如何使用 swift 清除和重绘 UIView 的内容(存在于视图控制器中)?【英文标题】:How to clear and redraw contents of a UIView (present inside a view controller) with swift? 【发布时间】:2017-01-05 06:57:46 【问题描述】:

我在View Controller 中有一个UIView,我在其中根据我的应用程序的要求画了几行。在某个时间点之后,我希望其中一些线条消失,而另一些线​​条则出现在同一个视图中。我现在使用的方法是清除 UIView 并重新绘制我想在更新后的视图中绘制的所有线条。

谁能告诉我正确的方法是什么?我经历了各种听起来相似的问题,但并没有太大帮助。到目前为止,我已经尝试过:-

outletView.setNeedsDisplay()

let context = UIGraphicsGetCurrentContext()
context?.clear(outletView.frame)

这些似乎都没有任何区别。

如果我再次致电viewDidLoad(),因为现在所有行都已更新。要绘制的新线条出现了,但应该消失的线条并没有消失。行变量已正确更新,因为我拥有的其他检查行变量值的逻辑在应该发生更新后工作正常。唯一的问题是重绘部分。事实上,如果我理解正确,问题只是清理旧的 uiview 内容。如果清洁正确进行,使用viewDidLoad 重绘将显示正确绘制的线条。

附:我知道明确调用viewDidLoad() 不是一个好习惯。希望不用再次调用viewDidLoad就能找到解决这个问题的办法。

【问题讨论】:

我不建议您明确调用 viewDidLoad。您在调用 setNeedsDisplay() 时遇到任何问题吗? 是的,我同意,我也不希望明确使用 viewDidLoad。使用 setNeedsDisplay,它什么也不做。在我想要切换线条的地方,我添加了以下代码:outletView.setNeedsDisplay() 但它根本没有重绘 UIView。阅读 Apple 文档 (developer.apple.com/reference/uikit/uiview/…) 后,我的理解是它仅标记要重绘的边界矩形,但并没有真正重绘自身。可能这就是为什么我没有看到任何重绘发生的原因? 我猜你在要绘制的视图中覆盖drawRect:并在该方法中执行绘制对吗? 不。我没有覆盖它。你能简单解释一下你的建议是什么吗?我可以试一试,看看它是否有效。 在你的视图上调用 setNeedsDisplay() 会通知系统你的视图的内容需要重绘。 setNeedsDisplay() 导致 drawRect: 在接收器上被调用,这就是为什么您应该覆盖该方法并在其中执行绘图的原因。使用此选项,您可能需要在视图上有一个属性,以跟踪需要绘制线条的位置,因为您想以两种不同的方式绘制线条。第二个选项是 @Ocunidee 建议的,是在 layoutSubviews 中使用 CAShapeLayer 进行绘制。使用前一种方法,在再次绘制之前清除上下文。 【参考方案1】:

也许您可以在视图的不同图层中绘制线条,删除包含需要消失的线条的图层并为新线条创建一个新图层。可以在layoutSubviews()中绘制,在需要更新视图时使用self.setNeedsLayout()

删除:

guard let sublayers = yourView.layer.sublayers else  return 
        for layer in sublayers 
            layer.removeFromSuperlayer()
        

添加:

let linesPath = UIBezierPath()
let linesLayer = CAShapeLayer()
linesPath.move(to: CGPoint(x: 0, y: 0)
linesPath.addLine(to: CGPoint(x: 50, y: 100)
lineLayer.path = linesPath.cgPath
linesLayer.lineWidth = 1.0
linesLayer.strokeColor = UIColor.black
yourView.layer.addSublayer(linesLayer)

【讨论】:

我接受了您的建议,使用 removeFromSuperLayer 删除图层适用于我的用例。非常感谢您的帮助。 :) 很高兴 ;)

以上是关于如何使用 swift 清除和重绘 UIView 的内容(存在于视图控制器中)?的主要内容,如果未能解决你的问题,请参考以下文章

当设备方向更改 SWIFT 5 时重绘自定义 UIVIEW

tableView、视图层次结构和重绘的绝对定位

如何使用故事板、initWithCoder、viewDidLoad 和 viewDidLayoutSubviews 有效地管理屏幕尺寸更改和重绘?

面试系列一如何回答如何理解重排和重绘

面试系列一如何回答如何理解重排和重绘

回流(重排)与重绘 —— 什么是回流和重绘,造成的原因是什么,如何去减少?