UIScrollView缩放时保持绘制元素清晰的实现方案咨询
解决方案
问题根源是缩放时DrawView的图层像素密度不足,导致绘制内容被拉伸后像素化。要同时保持元素宽度比例和清晰显示,核心是让图层的像素密度随缩放比例同步提升,同时维持绘制元素的物理尺寸不变。
步骤1:修改DrawView,动态调整图层像素密度
在DrawView中,监听zoomScale的变化,同步更新contentScaleFactor(图层的像素比例),确保图层有足够的像素来承载缩放后的内容:
public class DrawView: UIView { public var zoomScale: CGFloat = 1.0 { didSet { // 让图层像素密度 = 缩放比例 × 屏幕原生像素密度 contentScaleFactor = zoomScale * UIScreen.main.scale setNeedsDisplay() } } public override func draw(_ rect: CGRect) { drawLine() drawString() } private func drawLine() { let path = UIBezierPath() path.move(to: CGPoint(x:100, y:300)) path.addLine(to: CGPoint(x: 100, y: 400)) UIColor.red.set() // 线条宽度 = 目标物理宽度 / 缩放比例,保证屏幕上显示宽度不变 path.lineWidth = 2 / zoomScale path.stroke() } private func drawString() { // 字体大小 = 目标物理大小 / 缩放比例,保证屏幕上显示大小不变 let font = UIFont.systemFont(ofSize: 30 / zoomScale) let string = NSAttributedString(string: "Test", attributes: [ NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: UIColor.red ]) string.draw(at: CGPoint(x: 200, y: 200)) } }
步骤2:优化ViewController的缩放逻辑
在ViewController中,实时同步滚动视图的缩放比例到DrawView,不需要等到缩放结束再更新:
class ViewController: UIViewController { @IBOutlet private weak var scrollView: UIScrollView! @IBOutlet private weak var drawView: DrawView! override func viewDidLoad() { super.viewDidLoad() scrollView.maximumZoomScale = 20.0 scrollView.minimumZoomScale = 0.1 scrollView.zoomScale = 1.0 scrollView.backgroundColor = .lightGray scrollView.delegate = self } } extension ViewController: UIScrollViewDelegate { func viewForZooming(in scrollView: UIScrollView) -> UIView? { return drawView } // 实时同步缩放比例,避免缩放过程中出现模糊 func scrollViewDidZoom(_ scrollView: UIScrollView) { drawView.zoomScale = scrollView.zoomScale } }
原理说明
contentScaleFactor决定了图层的像素数量:当缩放比例为20时,图层像素数会是原来的20倍,足够承载清晰的矢量绘制内容。- 绘制时用
目标尺寸 / 缩放比例计算线条宽度和字体大小,确保元素在屏幕上的物理尺寸始终保持不变,不受缩放影响。
内容的提问来源于stack exchange,提问作者iOS
相关产品推荐
相关产品推荐

