【问题标题】:UITextView Fonts are bluring after Zoom IN放大后 UITextView 字体模糊
【发布时间】:2021-04-15 12:41:15
【问题描述】:

我用 UIScrollView、UIView 和 UITextView 创建了一个小项目(层次结构也是一样的。)。 UIView 显示为红色,UITextView 显示为蓝色。然后我在 UITextView 中添加了大小为 14 的 UIFont。

由于我想为此启用放大/缩小功能,我已将 UIScrollViewDelegate 添加到此控制器并覆盖 viewForZooming 方法。 然后放大/缩小除一件事外一切正常。

当我放大屏幕时,我可以看到 UITextView 中的字体模糊。我想在放大完成后根据缩放比例保持字体质量。所以我覆盖了 scrollViewDidEndZooming 并调整了它不起作用的 textView 帧大小。 谷歌搜索后,我找到了一些答案,但我尝试了但找不到解决方案,其中大多数都是非常旧的答案。

所以我恳请你们帮助我解决这个问题,我非常感谢你们的反馈和帮助。我附上了我的源代码和截图供你参考。

代码:


class ViewController: UIViewController {

    var scrollView: UIScrollView!
    var mainView: UIView!
    var textView: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        scrollView = UIScrollView(frame: .zero)
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(scrollView)
        NSLayoutConstraint.activate([
            scrollView.widthAnchor.constraint(equalTo: self.view.widthAnchor),
            scrollView.heightAnchor.constraint(equalTo: self.view.heightAnchor),
        ])
        
        mainView = UIView(frame: .zero)
        mainView.translatesAutoresizingMaskIntoConstraints = false
        mainView.backgroundColor = UIColor.red
        scrollView.addSubview(mainView)
        NSLayoutConstraint.activate([
            mainView.widthAnchor.constraint(equalToConstant: 600),
            mainView.heightAnchor.constraint(equalToConstant: 400),
            mainView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
            mainView.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor)
        ])
        
        textView = UITextView(frame: .zero)
        textView.translatesAutoresizingMaskIntoConstraints = false
        textView.backgroundColor = UIColor.blue
        textView.font = UIFont(name: "Thonburi", size: 14)
        textView.text = "Hello World"
        textView.textAlignment = .center
        mainView.addSubview(textView)
        NSLayoutConstraint.activate([
            textView.widthAnchor.constraint(equalToConstant: 200),
            textView.heightAnchor.constraint(equalToConstant: 40),
            textView.centerXAnchor.constraint(equalTo: mainView.centerXAnchor),
            textView.centerYAnchor.constraint(equalTo: mainView.centerYAnchor),
        ])
        
        scrollView.pinchGestureRecognizer?.isEnabled = true
        scrollView.maximumZoomScale = 12.0
        scrollView.minimumZoomScale = 0.2
        scrollView.delegate = self
    }


}

extension ViewController: UIScrollViewDelegate {
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        if let viewForZoom = scrollView.subviews.filter({$0.tag == 1}).first {
            return viewForZoom
        } else {
            return scrollView.subviews.first
        }
    }
    
    func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
        self.textView.frame = CGRect(origin: textView.frame.origin, size: CGSize(width: textView.frame.width*scale, height: textView.frame.height*scale))
    }
}

没有缩放,只是正常的屏幕尺寸

字体模糊,放大后

【问题讨论】:

  • 查看这个答案:stackoverflow.com/a/65511223/6257435 了解正在发生的事情。
  • 是的,我检查了那个答案,它设置为最小缩放比例为 0.1,最大缩放比例为 1.0。最初它具有大字体大小和从 0.1 X 字体大小计算的实际大小。当它具有最小缩放比例时,字体显示为高质量和压缩模式。
  • 是的,但这是否有助于您了解为什么字体模糊?您更改 textView 的 frame 的方法将无济于事。要在不同的缩放比例下获得清晰的字体,您将无法使用 scrollView 的缩放功能——您可能需要构建自己的“缩放”功能,使用捏合手势来计算比例,然后重新调整 textView 的大小并重新定位 更改其字体大小。
  • @DonMag 非常感谢您的反馈,但我只需要使用滚动视图而不是捏合手势。我想获得清晰的字体,但只有在完成缩放事件之后。这意味着我需要在 ScrollViewDelegate 的 scrollViewDidEndZooming 方法中添加此逻辑。重绘textView后,我是否也应该将缩放比例设置为1.0?如果主视图有多个项目,如贝塞尔路径形状对象,我应该重绘所有吗?
  • 有多种方法可以模拟滚动视图的功能,而无需使用滚动视图。但是,如果您真的想使用滚动视图,是的...您需要重新绘制所有内容,更改各个元素的“比例”(更改字体大小,更改贝塞尔路径的控制点等)和将滚动视图的 zoomScale 重置为 1.0

标签: ios uiscrollview swift5 uifont pinchzoom


【解决方案1】:

最后,我能够使用 contentScale 解决此问题,它应该更新 UIView 以及 UIView 和子视图的层和特定 UIView 的子层。否则,它将无法正常工作。

func scaleView( view: UIView, scale: CGFloat ){
    view.contentScaleFactor = scale
    for vi in view.subviews {
        scaleView(view: vi, scale: scale)
    }
}

func scaleLayer( layer: CALayer, scale: CGFloat ){
    layer.contentsScale = scale
    if layer.sublayers == nil {
        return
    }
    for la in layer.sublayers! {
        scaleLayer(layer: la, scale: scale)
    }
}

我们应该在scrollViewDidEndZooming(继承自UIScrollViewDelegate)方法中调用UITextView的上述两个方法。

func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
        scaleView(view: textView, scale: scale)
        scaleLayer(layer: textView.layer, scale: scale)
    }

但对于缩小功能,请不要直接设置比例值,否则质量会下降。所以需要保持阈值,应该根据你的使用情况来计算。

【讨论】:

    猜你喜欢
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-01
    • 1970-01-01
    相关资源
    最近更新 更多