xcode 如果标签太长,如何在结尾淡出标签,而不是用“...”替换结尾/如何使用GoogleToolboxForMac

k0pti3hp  于 2022-11-17  发布在  Go
关注(0)|答案(2)|浏览(124)

我从GoogleToolboxForMac中找到了一个GTMFadeTruncatingLabelTest的解决方案,但我并不真正了解如何使用它,也没有找到任何关于它的信息
但如果你有其他的解决方案
如果您不能帮助我使用GoogleToolboxForMac,请随时建议其他解决方案
结尾应该是这样的:

g9icjywg

g9icjywg1#

我不确定GTMFadeTruncatingLabelTest,但我可以提供一个替代解决方案。

步骤

1.检查标签的文本是否将被截断
1.如果1为true,则创建从不透明变为透明的CAGradientLayer
1.将渐变图层作为遮罩应用于UILabel

实施

如果你不想读剩下的,就grab the code from this repo
我把上面的步骤1、2和3 Package 在一个自定义的UILabel子类中,原因在注解中解释。

class FadingLabel: UILabel
{
    // Add a property observer for text changes
    // as we might not need to fade anymore
    override var text: String?
    {
        didSet
        {
            // Check if the text needs to be faded
            fadeTailIfRequired()
        }
    }
    
    // Add a property observer for numberOfLines changes
    // as only 1 line labels are supported for now
    override var numberOfLines: Int
    {
        didSet
        {
            // Reset the number of lines to 1
            if numberOfLines != 1
            {
                numberOfLines = 1
            }
        }
    }
    
    override func layoutSubviews()
    {
        super.layoutSubviews()
        
        // The label's frame might have changed so check
        // if the text needs to be faded or not
        fadeTailIfRequired()
    }
    
    
    /// The function that handles fading the tail end of the text if the text goes
    /// beyond the bounds of the label's width
    private func fadeTailIfRequired()
    {
        // Reset the numberOfLines to 1
        numberOfLines = 1
        
        // Prevent processing fading when the library is in the middle of
        // processing the string to truncate the ellipsis
        if !isTruncatingEllipsis
        {
            // Check if the label's has it's width set and if the text goes
            // beyond it's width plus a margin of safety
            if bounds.width > CGFloat.zero && intrinsicContentSize.width > bounds.width + 5
            {
                // Fade label works better with this setting
                allowsDefaultTighteningForTruncation = true
                
                // Initialize and configure a gradient to start at the end of
                // the label
                let gradient = CAGradientLayer()
                gradient.frame = bounds
                gradient.colors = [UIColor.white.cgColor, UIColor.clear.cgColor]
                gradient.startPoint = CGPoint(x: 0.8, y: 0.5)
                gradient.endPoint = CGPoint(x: 0.99, y: 0.5)
                
                // Apply the gradient as a mask to the UILabel
                layer.mask = gradient
                
                // Remove ellipsis added as the default UILabel truncation character
                removeEllipsis()
                
                // We do not need to go beyond this point
                return
            }
            
            // If the text has not been truncated, remove the gradient mask
            if originalText == text
            {
                // Remove the layer mask
                layer.mask = nil
            }
        }
    }
    
    /// Keep removing 1 character from the label till it no longer needs to truncate
    private func removeEllipsis()
    {
        isTruncatingEllipsis = true
        
        // Keep looping till we do not have the perfect string length
        // to fit into the label
        while intrinsicContentSize.width > bounds.width
        {
            // Drop the last character
            text = String(text!.dropLast())
        }
        
        isTruncatingEllipsis = false
    }
}

然后,您可以像使用一般的UILabel一样使用它,例如:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    let fadingLabelWithLongText = FadingLabel()
    view.addSubview(fadingLabelWithLongText)
    fadingLabelWithLongText.text = "Fading label with text more than it's bounds can handle"
    fadingLabelWithLongText.textColor = .white
    fadingLabelWithLongText.frame = CGRect(x: 20, y: 90, width: 250, height: 50)
    
    let regularLabelWithLongText = UILabel()
    view.addSubview(regularLabelWithLongText)
    regularLabelWithLongText.text = "Regular label with text more than it's bounds can handle"
    regularLabelWithLongText.textColor = .white
    regularLabelWithLongText.frame = CGRect(x: 20, y: 160, width: 250, height: 50)
    
    let fadingLabelWithShortText = UILabel()
    view.addSubview(fadingLabelWithShortText)
    fadingLabelWithShortText.text = "Fading label with text that fits"
    fadingLabelWithShortText.textColor = .white
    fadingLabelWithShortText.frame = CGRect(x: 20, y: 230, width: 250, height: 50)
    
    let regularLabelWithShortText = UILabel()
    view.addSubview(regularLabelWithShortText)
    regularLabelWithShortText.text = "Regular label with text that fits"
    regularLabelWithShortText.textColor = .white
    regularLabelWithShortText.frame = CGRect(x: 20, y: 300, width: 250, height: 50)
}

输出

限制

此方式仅支持单行UILabels

更新

添加了一个函数,以删除通过UILabel使用省略号(三个点)的默认截断方法。

/// Keep removing 1 character from the label till it no longer needs to truncate
private func removeEllipsis()
{
    isTruncatingEllipsis = true
    
    // Keep looping till we do not have the perfect string length
    // to fit into the label
    while intrinsicContentSize.width > bounds.width
    {
        // Drop the last character
        text = String(text!.dropLast())
    }
    
    isTruncatingEllipsis = false
}

此函数已在上述原始代码和repo中更新。

iqjalb3h

iqjalb3h2#

我认为最简单的方法是使用下面的代码:

titleLabel.adjustsFontSizeToFitWidth = false
titleLabel.lineBreakMode = .byClipping

如果适用,它会自动淡化最后一个单词,并且文本大小的宽度大于UILabel!
thanks to thi

相关问题