iOS UILabel将文本自动调整为框架大小,而不考虑字体

iOS UILabel将文本自动调整为框架大小,而不考虑字体,ios,swift,uilabel,font-size,Ios,Swift,Uilabel,Font Size,我有一件非同寻常的事情需要完成,但不知道如何完成 我有一个UILabel,希望将其设置为特定高度,然后调整其中文本的大小,使第一个字符等于该特定高度,其余字符仅获得计算出的字体大小 我已尝试使用myLabel.adjustsFontSizeToFitWidth=YES;但它并没有真正解决我的问题,因为它在文本中使用了greates字符,并且仍然添加了字体可能具有的垂直填充/间距 图片应该描述我想要完成的事情。可以看到高度应该是200px,第一个字符正好是200px,没有垂直添加任何填充/间距 有

我有一件非同寻常的事情需要完成,但不知道如何完成

我有一个UILabel,希望将其设置为特定高度,然后调整其中文本的大小,使第一个字符等于该特定高度,其余字符仅获得计算出的字体大小

我已尝试使用myLabel.adjustsFontSizeToFitWidth=YES;但它并没有真正解决我的问题,因为它在文本中使用了greates字符,并且仍然添加了字体可能具有的垂直填充/间距

图片应该描述我想要完成的事情。可以看到高度应该是200px,第一个字符正好是200px,没有垂直添加任何填充/间距

有人知道怎么解决这个问题吗

提前谢谢 瓦丹

如果希望UILabel的高度始终与第一个字符的高度匹配,可以使用sizeToFit,但不包括整个字符串,只包括第一个字符。然后,在计算完UILabel的框架后,仅基于第一个字母,就可以添加其余文本,标签仍将处于所需的高度

我希望这有帮助。祝你好运

编辑:您可以根据这些UIFont特征获得所需字符的确切高度。这张图片很好地解释了这一点。您可能需要根据当前正在处理的角色进行稍微不同的计算,但是,如图所示,您拥有计算所需的所有数据:

设置字体后,请执行此操作

CGSize sizeAsPerText = [labelAutoResizeCheck.text sizeWithFont:labelAutoResizeCheck.font];
[labelAutoResizeCheck setFrame:CGRectMake(labelAutoResizeCheck.frame.origin.x, labelAutoResizeCheck.frame.origin.y, sizeAsPerText.width, sizeAsPerText.height)];

一种基于渲染图像的解决方案,其中标签以字体大小显示,我们可以获得角色的起始位置和结束位置。通过这个,我们可以确定当前字符的高度(以像素为单位)。下一部分是给标签一个新的字体大小,然后通过渲染图像重复上一步。这将提供相同大小的字符,无论字体如何

要使用它,您需要向控制器添加以下代码,然后只需调用setSizeFont sizeFont:CGFloat,center:CGPoint方法,其中sizeFont是字符所需的大小,center是放置标签的位置。我需要在程序中使用此参数,它可能对其他人没有用处

如果解决方案可以改进,请随时编辑

extension UIImage {
    func getPixelColor(pos: CGPoint) -> UIColor {

        var pixelData = CGDataProviderCopyData(CGImageGetDataProvider(self.CGImage))
        var data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

        var pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4

        var r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
        var g = CGFloat(data[pixelInfo+1]) / CGFloat(255.0)
        var b = CGFloat(data[pixelInfo+2]) / CGFloat(255.0)
        var a = CGFloat(data[pixelInfo+3]) / CGFloat(255.0)

        return UIColor(red: r, green: g, blue: b, alpha: a)
    }

    private func getHeight() -> Int {
        var startHeight = 0
        var endHeight = Int(round(self.size.height))
        outerLoop: for var index = 0; index < Int(round(self.size.height)); index++ {
            for var j = 0; j < Int(round(self.size.width)); j++ {
                if(self.getPixelColor(CGPoint(x:j, y:index)) == UIColor(red: 0, green: 0, blue: 0, alpha: 1)) {
                    startHeight = index
                    break outerLoop
                }
            }
        }

        outerLoop: for var index = Int(round(self.size.height))-1; index >= 0; index -= 1 {
            for var j = 0; j < Int(round(self.size.width)); j++ {
                if(self.getPixelColor(CGPoint(x:j, y:index)) == UIColor(red: 0, green: 0, blue: 0, alpha: 1)) {
                    endHeight = index

                    break outerLoop
                }
            }
        }

        return endHeight-startHeight
    }
}

extension UILabel {
    func setSizeFont (sizeFont: CGFloat, center:CGPoint) {

        var str = self.text!
        str = str.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

        var tempLabel = UILabel(frame: self.frame)
        //Set text to only be the first char
        tempLabel.text = str.substringWithRange(Range<String.Index>(start: advance(str.startIndex, 0), end: advance(str.startIndex, 1)))
        tempLabel.font = UIFont(name: self.font.fontName, size: sizeFont)!
        tempLabel.backgroundColor = UIColor.whiteColor()
        tempLabel.textColor = UIColor.blackColor()
        tempLabel.sizeToFit()


        self.font =  UIFont(name: self.font.fontName, size: sizeFont)!


        var height = tempLabel.generateImg().getHeight()
        var sizeF = Int(round(sizeFont))
        var currSize = sizeF

        while( height < sizeF ) {
            var diff = sizeF - height
            if(diff<=5){
                currSize++
            } else {
                currSize += diff-5
            }
            tempLabel.font = UIFont(name: tempLabel.font.fontName, size: CGFloat(currSize))!
            tempLabel.sizeToFit()
            height = tempLabel.generateImg().getHeight()
        }

        self.font = UIFont(name: self.font.fontName, size: CGFloat(currSize))

        self.sizeToFit()

        self.center = center

    }
    private func generateImg() -> UIImage{

        UIGraphicsBeginImageContext(self.bounds.size);

        // Make the CALayer to draw in our "canvas".
        self.layer.renderInContext(UIGraphicsGetCurrentContext())

        // Fetch an UIImage of our "canvas".
        var image = UIGraphicsGetImageFromCurrentImageContext();

        // Stop the "canvas" from accepting any input.
        UIGraphicsEndImageContext();

        return image
    }

}

如果我将字体设置为200px,字符将不完全是200px,因为它在顶部和底部都有一些间距,在使用SizeToFit签出我添加到原始答案的链接之前,我需要删除这些间距。我希望它能为您提供解决问题所需的一切。谢谢,我会检查它,稍后再与您联系。嗨,我一直在努力找出第一个字符应该使用哪个值。是否有可能找出一个字符是否有升序、降序等?我认为你应该根据第一个字符使用的特定字符来确定。第一个字符为“x”的情况下的计算结果与第一个字符为“p”的情况下的计算结果不同。例如,如果字符为“a”,则您要查找的高度将仅为xHeight。但是,如果字符为“k”,则高度将为capHeight。对于'q',您将使用xHeight下降器。我希望这能有所帮助……嗨,既然有些函数不存在,我该如何用swift和xcode 6编写呢?@VatanBytyqi在我的xcode 6.4上,对于swift,在将文本和字体设置为标签后,我只需执行label.sizeToFit。如果你更详细地检查它,你会发现字符的大小并不完全是首选的大小,因为字体对于不同类型的och字符有一定的间距。
extension UIImage {
    func getPixelColor(pos: CGPoint) -> UIColor {

        var pixelData = CGDataProviderCopyData(CGImageGetDataProvider(self.CGImage))
        var data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

        var pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4

        var r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
        var g = CGFloat(data[pixelInfo+1]) / CGFloat(255.0)
        var b = CGFloat(data[pixelInfo+2]) / CGFloat(255.0)
        var a = CGFloat(data[pixelInfo+3]) / CGFloat(255.0)

        return UIColor(red: r, green: g, blue: b, alpha: a)
    }

    private func getHeight() -> Int {
        var startHeight = 0
        var endHeight = Int(round(self.size.height))
        outerLoop: for var index = 0; index < Int(round(self.size.height)); index++ {
            for var j = 0; j < Int(round(self.size.width)); j++ {
                if(self.getPixelColor(CGPoint(x:j, y:index)) == UIColor(red: 0, green: 0, blue: 0, alpha: 1)) {
                    startHeight = index
                    break outerLoop
                }
            }
        }

        outerLoop: for var index = Int(round(self.size.height))-1; index >= 0; index -= 1 {
            for var j = 0; j < Int(round(self.size.width)); j++ {
                if(self.getPixelColor(CGPoint(x:j, y:index)) == UIColor(red: 0, green: 0, blue: 0, alpha: 1)) {
                    endHeight = index

                    break outerLoop
                }
            }
        }

        return endHeight-startHeight
    }
}

extension UILabel {
    func setSizeFont (sizeFont: CGFloat, center:CGPoint) {

        var str = self.text!
        str = str.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

        var tempLabel = UILabel(frame: self.frame)
        //Set text to only be the first char
        tempLabel.text = str.substringWithRange(Range<String.Index>(start: advance(str.startIndex, 0), end: advance(str.startIndex, 1)))
        tempLabel.font = UIFont(name: self.font.fontName, size: sizeFont)!
        tempLabel.backgroundColor = UIColor.whiteColor()
        tempLabel.textColor = UIColor.blackColor()
        tempLabel.sizeToFit()


        self.font =  UIFont(name: self.font.fontName, size: sizeFont)!


        var height = tempLabel.generateImg().getHeight()
        var sizeF = Int(round(sizeFont))
        var currSize = sizeF

        while( height < sizeF ) {
            var diff = sizeF - height
            if(diff<=5){
                currSize++
            } else {
                currSize += diff-5
            }
            tempLabel.font = UIFont(name: tempLabel.font.fontName, size: CGFloat(currSize))!
            tempLabel.sizeToFit()
            height = tempLabel.generateImg().getHeight()
        }

        self.font = UIFont(name: self.font.fontName, size: CGFloat(currSize))

        self.sizeToFit()

        self.center = center

    }
    private func generateImg() -> UIImage{

        UIGraphicsBeginImageContext(self.bounds.size);

        // Make the CALayer to draw in our "canvas".
        self.layer.renderInContext(UIGraphicsGetCurrentContext())

        // Fetch an UIImage of our "canvas".
        var image = UIGraphicsGetImageFromCurrentImageContext();

        // Stop the "canvas" from accepting any input.
        UIGraphicsEndImageContext();

        return image
    }

}