【问题标题】:Quality of scaled-down UILabels缩小的 UILabel 的质量
【发布时间】:2017-11-15 14:50:27
【问题描述】:

我正在使用 Swift 3 创建一个 iOS 界面,其中一些包含(除其他外)UILabels 的 UIViews 会根据它们在屏幕上的位置进行放大和缩小。我的第一种方法是以舒适的大尺寸(比如 100x100)创建和填充视图,然后根据需要使用 CGAffineTransform(scaleX:y:) 缩放它们,但是我注意到标签中文本的缩小一点也不优雅,并且文本在小范围内变得像素化并且接近不可读。作为比较(参见下面的示例),直接更改字体大小会产生更好的结果,但是我的视图中的结构有些复杂,并且必须根据某些大小因素重新绘制所有内容会很麻烦。有没有更好更顺畅的方法来解决这个问题?

这是我为说明问题而创建的示例项目,以及模拟器中的输出(与 iPhone 本身相同),缩小的视图位于左侧(红色),更改后的字体大小位于右侧(绿色)。

class ViewController: UIViewController {

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

        for i in 1...10 {
            let f = CGFloat(1.0) / CGFloat(i)
            let view1 = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
            view1.backgroundColor = UIColor.red
            let label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
            label1.text = "\(100 / i)%"
            label1.font = UIFont(name: "Verdana", size: 24.0)
            label1.textAlignment = .right
            view1.addSubview(label1)
            view1.transform = CGAffineTransform(scaleX: f, y: f)
            view1.center = CGPoint(x: 160 - 75.0 * f, y: CGFloat(60 * i) + 25.0 * f)
            self.view.addSubview(view1)

            let view2 = UIView(frame: CGRect(x: CGFloat(170), y: CGFloat(60 * i), width: 150 * f, height: 50 * f))
            view2.backgroundColor = UIColor.green
            let label2 = UILabel(frame: CGRect(x: 0, y: 0, width: 150 * f, height: 50 * f))
            label2.text = "\(100 / i)%"
            label2.font = UIFont(name: "Verdana", size: 24.0 * f)
            view2.addSubview(label2)
            self.view.addSubview(view2)

        }

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

【问题讨论】:

  • 自动布局在哪里?
  • 在这个例子中我没有使用任何自动布局,它只是手写代码
  • 是否需要将边界框缩放到特定大小?还是字体?你可以使用.adjustsFontSizeToFitWidth = true 让它自动缩放字体吗?
  • @DonMag 我可能弄错了,但我认为这不是正确的方法。方框中的文本大多是静态的,变化的是整个视图的大小,并且在视图的生命周期中可能会发生多次变化。据我了解,adjustFontSizeToFitWidth = true 可用于在文本对于边界框而言太大时更改文本大小,但在缩小视图时无济于事。我尝试将其添加到我的代码中,但无济于事。
  • @David - 如果您将标签大小设置为随其“容器视图”大小而变化,也许它会起作用。例如,请参阅我的答案。

标签: ios swift uiview uilabel scaling


【解决方案1】:

这可能是一个答案 - 但不太适合发表评论,所以...

试一试 - 它使用.adjustsFontSizeToFitWidth 创建黄色背景视图的第三“列”。字体大小将根据包含标签的视图大小自动调整。

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

    for i in 1...10 {
        let f = CGFloat(1.0) / CGFloat(i)
        let view1 = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
        view1.backgroundColor = UIColor.red
        let label1 = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
        label1.text = "\(100 / i)%"
        label1.font = UIFont(name: "Verdana", size: 24.0)
        label1.textAlignment = .right
        view1.addSubview(label1)
        view1.transform = CGAffineTransform(scaleX: f, y: f)
        view1.center = CGPoint(x: 160 - 75.0 * f, y: CGFloat(60 * i) + 25.0 * f)
        self.view.addSubview(view1)

        let view2 = UIView(frame: CGRect(x: CGFloat(170), y: CGFloat(60 * i), width: 150 * f, height: 50 * f))
        view2.backgroundColor = UIColor.green
        let label2 = UILabel(frame: CGRect(x: 0, y: 0, width: 150 * f, height: 50 * f))
        label2.text = "\(100 / i)%"
        label2.font = UIFont(name: "Verdana", size: 24.0 * f)
        view2.addSubview(label2)
        self.view.addSubview(view2)

        let view3 = UIView(frame: CGRect(x: CGFloat(270), y: CGFloat(60 * i), width: 150 * f, height: 50 * f))
        view3.backgroundColor = UIColor.yellow
        let label3 = UILabel(frame: view3.bounds)
        label3.text = "\(100 / i)%"
        label3.font = UIFont(name: "Verdana", size: 24.0)
        label3.adjustsFontSizeToFitWidth = true
        label3.minimumScaleFactor = 0.05
        label3.numberOfLines = 0
        // we want the label to resize with the view, if the view frame changes
        label3.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view3.autoresizesSubviews = true
        view3.addSubview(label3)
        self.view.addSubview(view3)

    }
}

【讨论】:

  • 这绝对是一个进步,谢谢!唯一的小事是文本大小与外框大小之间的比率发生了变化,因为文本的大小受框架边界的限制,它实际上并没有“缩放”。所以我想我只需要将我的UILabels 包含在紧密的UIViews 中就可以使用该技术。在我的应用程序中,我有几段文本都必须根据外部视图的大小一起缩放,我需要一些中间层
  • 通过使用这种技术并将UILabel 包含在中间UIView 中,我能够几乎完全复制原始结果,同时保持高质量并且不手动更改字体大小。然后我不得不调整高度(字体大小 * 1.25)以考虑文本周围的空间。可能有更好/更简单的方法来做到这一点,但至少这个方法可行并且看起来不错。
  • @David - (几乎)总是有不止一种做事方式......很高兴你得到了你想要的结果。
猜你喜欢
  • 2012-08-05
  • 2011-09-01
  • 2012-06-22
  • 1970-01-01
  • 1970-01-01
  • 2015-05-13
  • 1970-01-01
  • 2015-10-18
  • 2016-12-09
相关资源
最近更新 更多