首页 文章

在UILabel - Swift中拟合文本

提问于
浏览
0

我正在努力将文字装入UILabel . 我希望UILabel的宽度保持不变,但我想要更改文本的字体大小,以便所有文本都能够适合标签 . 我基本上创建了一个包含文本项的菜单栏:今天,明天,本周,下周 . 这是我的标签设置:

class MenuCell: BaseCell {

let dateLabel: UILabel = {
    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    label.backgroundColor = UIColor(red: 247/255, green: 199/255, blue: 199/255, alpha: 1)
    label.sizeToFit()
    label.textAlignment = .center
    label.adjustsFontForContentSizeCategory = true
    label.allowsDefaultTighteningForTruncation = true
    label.numberOfLines  =   2
    label.lineBreakMode  =  NSLineBreakMode.byTruncatingTail
    label.adjustsFontSizeToFitWidth    =   true
    label.minimumScaleFactor           =    10/UIFont.labelFontSize
    return label
}()

我有这个函数的特定宽度高度大小:

func collectionView(_ collectionView: UICollectionView, layout 
 collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: frame.width / 4, height: frame.height)

}

我设置了这些单元格:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! MenuCell
    cell.dateLabel.text = labelnames[indexPath.item]


  cell.backgroundColor = UIColor(red: 247/255, green: 199/255, blue: 199/255, alpha: 1)

    return cell
}

最后,要将单元格添加到视图中,我会:

override func setupViews(){
super.setupViews()
addSubview(dateLabel)
dateLabel.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
}

我将整个视图放在导航栏下方的其他视图控制器文件中:

lazy var menuBar: MenuBar = {
    let mb = MenuBar()
    mb.homeController = self
    return mb
}()
private func setupMenuBar() {
    view.addSubview(menuBar)
    view.addConstraintsWithFormat(format: "H:|[v0]|", views: menuBar)
    view.addConstraintsWithFormat(format: "V:|-64-[v0(50)]", views: menuBar)    
}

但由于某种原因,我所拥有的文字并没有改变字体大小以适应UIlabel单元格 . 尝试拟合的文本示例: let labelnames = ["Todayyyyyyyyyy","Tomorrow", "This Week", "Next Week"] "Todayyyyyyyyyy"未更改字体大小以适合所有方式 . 还有哪些其他属性可以调整以解决我的问题?

2 回答

  • 0

    OPTION #1 -- AUTO ADJUST

    将字体大小设置为较大,并根据需要将其缩小,如下所示:

    label.adjustsFontSizeToFitWidth = true
    label.minimumScaleFactor = 0.01
    

    您只需将初始大小设置为巨大 . 它只能缩小,而不是缩小 .

    这里的缺点是,如果你做了一些非常大的事情,比如:

    label.font = UIFont.systemFont(ofSize: 500)
    label.adjustsFontSizeToFitWidth = true
    label.minimumScaleFactor = 0.0001
    

    默认情况下,标签的高度将基于500 .

    OPTION #2 -- MANUALLY ADJUST FOR TIGHTER FIT

    func updateLabel(_ s: String, label: UILabel) {
    
        var size = 222 as CGFloat
        repeat {
            let textSize = s.size(withAttributes:[.font: UIFont.systemFont(ofSize:size)])
            if textSize.width <= label.frame.width {
                break
            }
            size -= 0.10
    
        } while (size > 4)
        label.font = UIFont.systemFont(ofSize: size)
        label.text = s
    }
    

    快速示例:videosource code . 上面的标签使用选项#1,底部标签使用选项#2 .

    您可以看到选项#2比系统管理方式更好 . 它可能也更加CPU密集,但如果你只是每个标签执行一次这可能无关紧要 .

    可能是您的标签框架不是您认为的大小,因为您只设置 topAnchor . 你也在设置其他人或做宽度限制或其他什么?

    如果标签应该填充单元格,您可以执行以下操作:

    override func setupViews(){
        super.setupViews()
    
        addSubview(dateLabel)
        dateLabel.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        dateLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        dateLabel.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
        dateLabel.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
    }
    

    另一个建议是在Xcode中运行应用程序,然后使用视图调试工具 - 单击此项:

    view debugger

    这将显示Xcode中屏幕的分解视图,以及所有视图的框架 . 检查标签是否真的是您认为的大小 .

  • 0

    这是我将如何做到的(我喜欢使用 @IBDesignable 所以我也可以在故事板中自由使用它)

    extension UIFont {
        func sizeOfString (string: String, constrainedToWidth width: Double) -> CGSize {
            return NSString(string: string).boundingRect(with: CGSize(width: width, height: Double.greatestFiniteMagnitude),
                                                         options: NSStringDrawingOptions.usesLineFragmentOrigin,
                                                                 attributes: [NSAttributedStringKey.font: self],
                                                                 context: nil).size
        }
    }
    
    @IBDesignable public class TestLabel: UILabel {
        @IBInspectable public var autoResize: Bool = false {
            didSet {
                decorate()
            }
        }
    
        @IBInspectable public var resizeStep: CGFloat = 1.0 {
            didSet {
                decorate()
            }
        }
    
        func decorate() {
            // Here you can change whatever you want
    
            var bestFontSize: CGFloat = 1
            var testedFontSize: CGSize = self.font.withSize(bestFontSize).sizeOfString(string: self.text!, constrainedToWidth: Double.greatestFiniteMagnitude)
            while testedFontSize.width < self.frame.width && testedFontSize.height < self.frame.height {
                bestFontSize += 1
                testedFontSize = self.font.withSize(bestFontSize).sizeOfString(string: self.text!, constrainedToWidth: Double.greatestFiniteMagnitude)
            }
            self.font = self.font.withSize(bestFontSize - self.resizeStep)
        }
    }
    

    我刚刚在操场上测试了它,所以我没有关心 boundscontentsRect ,但它只是为了展示你如何使用它 .

    尽管如此,不建议从设计的角度来做这件事 .

相关问题